Извлечение элементов из вложенного списка на основе элементов другого вложенного списка - PullRequest
0 голосов
/ 30 мая 2019

У меня есть два вложенных списка: один содержит идентификаторы пользователей и их индивидуальное местоположение, а второй - вложенные списки, содержащие первый элемент продукта и список идентификаторов пользователей, которые приобрели продукты.Мне нужно найти уникальные местоположения покупателей для каждого продукта.

Я могу получить результаты, используя вложенные циклы 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 ]

2 голосов
/ 30 мая 2019

Сначала вы хотите создать словарь пользователей, а затем вы можете использовать понимание вложенного списка, чтобы сопоставить их в одной строке кода

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 голос
/ 30 мая 2019

С 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'})]
1 голос
/ 30 мая 2019

[(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'])]

PS Может быть лучше переместить dict(users) к другой переменной.

0 голосов
/ 30 мая 2019

Однолинейное решение с использованием list comprehension

[(z [0], [j [1] для i в z [1] для j для пользователей, если j [0] == i]) для z в 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])

Надеюсь, это имеет значение. :)

0 голосов
/ 30 мая 2019

Использование списка и карты.

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'}}
0 голосов
/ 30 мая 2019

Вы можете сделать это:

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'})]
...