Для словаря сравните и ключ и значение со значениями в списке - PullRequest
1 голос
/ 07 ноября 2019

У меня есть следующие структуры:

prev = { 'alpha:10.2': '145', 'teta:180': '198', 'eltira:140': '222', 'ronta:23.14':220}
now = ['alpha:10.3','teta:180', 'eltira:142']

и следующий код:

   old = []
    for k, v in prev.iteritems():
     if k not in now:
       old.append(v)

Так что если ключ от dict prev не найден в списке now, Я добавляю значение в список old.

Результат 'old = [' 145 ',' 222 '] `

Но я также хочу проверить, какая часть не'т соответствуют от ключа. Я склонен использовать namedtuple.

Package = collections.namedtuple('Package', 'name version')

for k, v in prev.items():
  name, version = k.split(':')
  Package(name=k, version='v')
  1. , если name соответствует, а version нет, сделайте то же, что и выше.
  2. , если name не найден, добавьте его в новый список old_names, но также сделайте, как указано выше.

Проблема в том, что if k not in now не будет работать. Я могу сделать это с двумя циклами и тремя ifs, но, возможно, есть возможность сделать это более чистым.

Ожидаемый результат:

old=[ '145', '222'] old_names=['ronta']

Ответы [ 3 ]

0 голосов
/ 07 ноября 2019

Я разделил список «сейчас» и преобразовал его в словарь (имя: версия), который занимает одну итерацию. Позже к значениям из словаря можно обращаться в постоянное время для дальнейших операций.

prev = { 'alpha:10.2': '145', 'teta:180': '198', 'eltira:140': '222', 'old:1. 43':'150'}
now = ['alpha:10.3','teta:180', 'eltira:142']

now_dict = {}
old = []
old_names = []

for items in now:
  temp0,temp1 = items.split(':')
  now_dict[temp0] = temp1

for k,v in prev.items():
   name,version = k.split(':')
   if name not in now_dict.keys():
      old_names.append(name)
      old.append(v)
      continue

   if version != now_dict[name]:
      old.append(v)
      continue

   else:
     continue

if __name__ == '__main__':
  print(old_names)
  print(old)
0 голосов
/ 07 ноября 2019

Вы можете сделать now диктовкой, map добавив к ней operator.methodcaller и обернув ее в dict(), тогда понимание будет легким, если использовать тот же метод для prev:

splitter = operator.methodcaller('split', ':')
now_dict, kv_map = dict(map(splitter, now)), map(splitter, prev)

old = [prev[':'.join((k,v))] for k, v in kv_map if k in now_dict]
old_names = [n for n, v in kv_map if n not in now_dict]

Результаты:

#old
['145', '198', '222']
#old_names
[]
0 голосов
/ 07 ноября 2019

Вот способ сделать это:

prev = { 'alpha:10.2': '145', 'teta:180': '198', 'eltira:140': '222', 'zeta:12.1' : '334'}
now = ['alpha:10.3','teta:180', 'eltira:142']

now_splited = [nk.split(":") for nk in now]

old = []
old_name = []
for k, v in prev.items():
    if k not in new_key:
        old_n, old_v = k.split(":")
        name = any(map(lambda n : n[0] == old_n, now_splited))
        version = any(map(lambda n : n[1] == old_v, now_splited))
        if name and not version:
            old.append(v)
        elif not name:
            old_name.append(old_n
            old.append(old_v))

Результаты:

>>> print(old, old_name)
['145', '222', '334'] ['zeta']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...