As you might have discovered, the SPFieldLookup.LookupList property is Read Only, and cannot be set. I have a scenario where I’m trying to migrate a sub-site from one site collection to another, and the lookup list GUID will not be the same in the new site collection. I tried setting the LookupList property to the new GUID, but no dice. I got error. I knew there had to be a way around, and I found it. You have to do a string.Replace() on the SPField.SchemaXml, like so:

SPWeb web = [Whatever web your new list is in];
SPList newListToAttachTo = web.Lists["My New Lookup List"];
SPField myField = myList.Fields["My Field"];
string xml = myField.SchemaXml;
//Replace old LookupList ID with new one
xml = xml.Replace("c4ba59f4-b3e0-48f5-8f8c-6af7dd11b566", newListToAttachTo.ID.ToString());
//Replace old LookupWebId with new one
xml = xml.Replace("19c2dac4-c09f-4611-a0c6-1208ca641565", web.ID.ToString());
myField.SchemaXml = xml;
myField.Update();

Voila! Your lookup columns will now work. (If you need your code to be more dynamic, do a string search for the LookupList attribute and the LookupWebId attribute, and replace the GUID dynamically if necessary.)

As a side note, if you’re using the stsadm -o export process to export a particular sub-web, if you take a look at the contents of the export file, you’ll see an XML file called LookupListMap.xml. This is the holy grail for reattaching lookup list values to a different location in a new site. For every single lookup list item, there’s a URL property you can set, so when the import runs, the lookup list property will point to that URL.