我有两个嵌套列表-一个包含用户ID及其各自的位置,第二个嵌套列表包含产品的第一个元素和已购买产品的用户ID列表。我需要找到每种产品的购买者的唯一位置。
我能够通过使用嵌套的for循环来获得结果。但是,我希望列表理解也一样。我不想使用数据框或sql命令。
users=([1,'MX'],[2,'EN'],[3,'US'],[4,'FR'],[5,'US'],[6,'EN'],[7,'MX'])
prod=[
(1005,[5]),
(1004,[2,4,1]),
(1003,[3,5]),
(1002,[7,5,2]),
(1001,[6,5,1])
]
for p in prod:
prod_loc=[]
for u in p[1]:
for uloc in users:
if u==uloc[0]:
if uloc[1] not in prod_loc:
prod_loc.append(uloc[1])
else:
continue
print (p[0],prod_loc)
答案 0 :(得分:2)
您首先想创建一个用户字典,然后可以使用嵌套列表推导在单个代码行中匹配他们
dict_users = {x[0]: x[1] for x in users}
prod = [[x[0], [dict_users[y] for y in x[1]]] for x in prod]
如您所见,您正在遍历prod中的每个元素
[_ for x in prod]
具有与dict_users元素匹配的列表,列表中的每个元素
[x[0], [dict_users[y] for y in x[1]]]
答案 1 :(得分:1)
[(e[0], list(set(dict(users)[r] for r in e[1]))) for e in prod]
解释:
[
( # Tuple
e[0], # Prod name
list( # Convert to list
set( # Set of unique elements
dict(users)[r] # Get region of user
for r in e[1] # For each user in the list of prod
)
)
)
for e in prod # For each prod
]
结果:
[(1005, ['US']),
(1004, ['MX', 'EN', 'FR']),
(1003, ['US']),
(1002, ['MX', 'EN', 'US']),
(1001, ['US', 'EN', 'MX'])]
P.S。最好将dict(users)
移到另一个变量。
答案 2 :(得分:0)
您可以这样做:
from itertools import groupby
users=([1,'MX'],[2,'EN'],[3,'US'],[4,'FR'],[5,'US'],[6,'EN'],[7,'MX'])
prod=[
(1005,[5]),
(1004,[2,4,1]),
(1003,[3,5]),
(1002,[7,5,2]),
(1001,[6,5,1])
]
temp = [(p[0],u[1]) for p in prod for u in users if u[0] in p[1]]
result = []
for id, locations in groupby(temp, key=lambda x: x[0]):
result.append((id, {x[1] for x in locations}))
输出是:
[(1005, {'US'}), (1004, {'MX', 'FR', 'EN'}), (1003, {'US'}), (1002, {'EN', 'US', 'MX'}), (1001, {'MX', 'US', 'EN'})]
答案 3 :(得分:0)
带有defaultdict
和set
对象(“为每种产品找到购买者的唯一位置” ):
from collections import defaultdict
...
users_dict, result = dict(users), defaultdict(set)
for prod_id, user_ids in prod:
result[prod_id].update(set(users_dict.get(u_id) for u_id in user_ids))
result = list(result.items())
print(result)
输出:
[(1005, {'US'}), (1004, {'EN', 'MX', 'FR'}), (1003, {'US'}), (1002, {'US', 'MX', 'EN'}), (1001, {'EN', 'US', 'MX'})]
答案 4 :(得分:0)
使用列表理解和映射。
list(map(lambda x: (x[0], set([ul[1] for u in x[1] for ul in users if ul[0]==u])), prod))
输出
[(1005, {'US'}),
(1004, {'EN', 'FR', 'MX'}),
(1003, {'US'}),
(1002, {'EN', 'MX', 'US'}),
(1001, {'EN', 'MX', 'US'})]
要获取字典,只需将map
的输出传递到dict
。
dict(map(lambda x: (x[0], set([ul[1] for u in x[1] for ul in users if ul[0]==u])), prod))
输出
{1005: {'US'},
1004: {'EN', 'FR', 'MX'},
1003: {'US'},
1002: {'EN', 'MX', 'US'},
1001: {'EN', 'MX', 'US'}}
答案 5 :(得分:0)
list comprehension
的单行解决方案[[z [0],[j [1] for i in z [1] for i in users j if j [0] == i])for z in prod]
# How to solve this kinda problem step by step:
# First assume you have only one element in prod --> (1004, [2, 4, 1]).
# Now write a list comprehension to replace the [2, 4, 1] with ['MX', 'EN', 'FR'], this can be done using 2 for loops as below:
aa = [2, 4, 1]
print ([j[1] for i in aa for j in users if j[0] == i])
# Now perform above logic for the entire prod data using for loop and store desired result:
print ([(z[0], [j[1] for i in z[1] for j in users if j[0] == i]) for z in prod])
我希望这很重要。 :)