Python 3中的联接列表,例如SQL JOIN

时间:2019-01-21 09:49:24

标签: python python-3.x list join

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

O1:
field1(id)
field2
field3

O2:
field1
field2
field3(id)
field4

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

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

3 个答案:

答案 0 :(得分:1)

您可以通过简单而幼稚的方式做到这一点:

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

对于小名单,它肯定比熊猫有效得多,但对于大名单,它的性能会很差。

一种中间方法是使用辅助词典:

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模块处理非常大的数据集效率低,但比幼稚的方法处理不太小的列表要好得多。

答案 1 :(得分:0)

pandas具有许多以这种方式处理数据的功能。

将您的列表变成pd.DataFrame,然后您就可以使用pd.join。像SQL JOIN一样,它使您可以指定内部,左侧,右侧,外部等参数。

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

答案 2 :(得分:0)

如果我明白这一点,我会尝试举一个例子。假设您有以下课程:

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