I've noticed that setting `LookupList` and `LookupWebId` not always work. Therefor, I have a function that replace XML attributes in field schema. Take a look at the following code:

    public static string ReplaceXmlAttributeValue(string xml, string attributeName, string value)
    {
        if (string.IsNullOrEmpty(xml))
        {
            throw new ArgumentNullException("xml");
        }
        if (string.IsNullOrEmpty(value))
        {
            throw new ArgumentNullException("value");
        }
        int indexOfAttributeName = xml.IndexOf(attributeName, StringComparison.CurrentCultureIgnoreCase);
        if (indexOfAttributeName == -1)
        {
            xml = xml.Replace("<Field", "<Field " + attributeName + "='" + value + "'");
    
            return xml;
        }
        int indexOfAttibuteValueBegin = xml.IndexOf('"', indexOfAttributeName);
        int indexOfAttributeValueEnd = xml.IndexOf('"', indexOfAttibuteValueBegin + 1);
        return xml.Substring(0, indexOfAttibuteValueBegin + 1) + value + xml.Substring(indexOfAttributeValueEnd);
    }

I use it like this:
Get both lists and the lookup field that you want to set up:

    var mainList = web.GetList(SPUtility.ConcatUrls(web.ServerRelativeUrl, "Lists/MainList"));
    var mainListLookupField = (SPFieldLookup)mainList.Fields.GetFieldByInternalName("LookupField");
    var lookupList = web.GetList(SPUtility.ConcatUrls(web.ServerRelativeUrl, "Lists/LookupList"));

Replace `List` and `WebId` attributes in your Lookup Field's schema:

    mainListLookupField.SchemaXml = ReplaceXmlAttributeValue(ReplaceXmlAttributeValue(mainListLookupField.SchemaXml, "List", lookupList.ID.ToString()), "WebId", web.ID.ToString());
    mainListLookupField.LookupField = "Title";
    mainListLookupField.Update();

Hope this helps!