基于另一个嵌套列表的元素从嵌套列表中增加元素

时间:2019-05-30 10:41:13

标签: python list lambda list-comprehension

我有两个嵌套列表-一个包含用户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)

6 个答案:

答案 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)

带有defaultdictset对象(“为每种产品找到购买者的唯一位置” ):

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])

我希望这很重要。 :)