我有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关系),但不一定按这两个字段进行排序。
答案 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