【问题标题】:Joining lists in Python 3 like SQL JOIN在 Python 3 中加入列表,如 SQL JOIN
【发布时间】:2019-06-14 16:24:04
【问题描述】:

我有 2 个对象(将它们想象成数据库表):

O1:
字段 1(id​​)
字段2
字段3

氧气:
字段1
字段2
字段 3(id)
字段4

我有 2 个列表:
L1 是 O1 对象的列表
L2 是 O2 对象的列表

问题:有没有办法像 SQL JOIN 一样通过 L1.field1 和 L2.field3 加入这两个列表?两个列表的项数始终相等(1:1 关系),但不一定按这两个字段排序。

【问题讨论】:

    标签: python python-3.x list join


    【解决方案1】:

    你可以用简单天真的方式来做:

    joined = [ i + j for i in L1 for j in L2 if i[0] == j[2] ]
    

    对于小型列表,它肯定会比 pandas 更有效,但对于大型列表,效果会很差。

    中间的方法是使用辅助字典:

    D2 = { j[2]: j for j in L2 }
    joined = [ i + D2[i[0]] for i in L1 ]
    

    它将在 O(len(L1)) + O(len(L2)) 而不是 O(len(L1)) * O(len(L2)) 上执行。对于非常大的数据集,效率仍然低于高度优化的 pandas 模块,但对于不太小的列表来说,比简单的方法要好得多。

    【讨论】:

      【解决方案2】:

      pandas 有很多函数可以通过这种方式处理数据。

      将您的列表转换为pd.DataFrames,然后您就可以使用pd.join。与 SQL JOIN 一样,它允许您指定参数,如内部、左侧、右侧、外部。

      dfL1.set_index(field1).join(dfL2.set_index(field3))
      

      【讨论】:

        【解决方案3】:

        如果我明白了这一点,我会尝试展示一个例子。假设你有这些类:

        class User():
          def __init__(self, id, name):
            self.id = id
            self.name = name
        
        class Image():
          def __init__(self, id, user_id, filename):
            self.id = id
            self.user_id = user_id
            self.filename = filename
        

        还有以下收藏:

        users = [User(1, 'Jim'), User(2, 'Spock')]
        images = [Image(1, 1, 'jim_1.jpg'), Image(2, 1, 'jim_2.jpg'), Image(3, 2, 'spk_1.jpg')]
        

        从集合中获取用户后,假设是第一个:

        user = users[0]
        

        您可以通过这种方式查询图片:

        user_images = [ image for image in images if image.user_id == user.id ]
        
        for image in user_images:
          print(image.filename)
        

        如果你有图片,因为在这种情况下是一对多的关系:

        image = images[0]
        user = [user for user in users if user.id == image.user_id][0] # [0] as it is 1:n relation
        


        对于连接表:
        join_table = [ {'name': user.name, 'filename': image.filename} for user in users for image in images if user.id == image.user_id ]
        
        for e in join_table:
          print(e['name'], e['filename'])
        

        返回:

        # Jim jim_1.jpg
        # Jim jim_2.jpg
        # Spock spk_1.jpg
        

        【讨论】:

          猜你喜欢
          • 2016-10-14
          • 1970-01-01
          • 2011-01-14
          • 2015-10-10
          • 2018-07-25
          • 1970-01-01
          • 2015-09-21
          • 2015-10-26
          • 2020-09-15
          相关资源
          最近更新 更多