Перебор словарей с использованием циклов for

Я бы использовал Jaro-Winkler, потому что это один из наиболее эффективных и точных приближенных алгоритмов сопоставления строк, доступных в настоящее время [ Cohen, et al. ], [ Winkler ].

Так я сделал бы это с Jaro-Winkler из пакета медузы :

def get_closest_match(x, list_strings):

  best_match = None
  highest_jw = 0

  for current_string in list_strings:
    current_score = jellyfish.jaro_winkler(x, current_string)

    if(current_score > highest_jw):
      highest_jw = current_score
      best_match = current_string

  return best_match

df1 = pandas.DataFrame([[1],[2],[3],[4],[5]], index=['one','two','three','four','five'], columns=['number'])
df2 = pandas.DataFrame([['a'],['b'],['c'],['d'],['e']], index=['one','too','three','fours','five'], columns=['letter'])

df2.index = df2.index.map(lambda x: get_closest_match(x, df1.index))

df1.join(df2)

Выход:

    number  letter
one     1   a
two     2   b
three   3   c
four    4   d
five    5   e

2800
задан sberry 20 November 2017 в 21:39
поделиться

6 ответов

key - это просто имя переменной.

for key in d:

будет просто перебирать ключи в словаре, а не ключи и значения. Чтобы перебрать и ключ, и значение, можно использовать следующее:

Для Python 2.x:

for key, value in d.iteritems():

Для Python 3.x:

for key, value in d.items():

Чтобы проверить самостоятельно, измените слово key на poop.

Для Python 3.x iteritems() был заменен на просто items(), который возвращает представление, подобное множеству, подкрепленное dict, как iteritems(), но еще лучше. Это также доступно в 2.7 как viewitems().

Операция items() будет работать и в 2, и в 3, но в 2 она вернет список пар (key, value) словаря, который не будет отражать изменения в dict, произошедшие после вызова items(). Если вы хотите получить поведение 2.x в 3.x, вы можете вызвать list(d.items()).

5072
ответ дан 22 November 2019 в 19:47
поделиться

Дело не в том, что key - это особое слово, а в том, что словари реализуют протокол итератора. Вы можете сделать это в своем классе, например, смотрите этот вопрос о том, как построить итераторы класса.

В случае со словарями это реализовано на уровне C. Подробности можно найти в PEP 234. В частности, в разделе "Dictionary Iterators":

  • Словари реализуют слот tp_iter, который возвращает эффективный итератор, который выполняет итерацию по ключам словаря. [...] Это означает, что мы можем написать

    for k in dict: ...
    

    что эквивалентно, но гораздо быстрее, чем

    for k in dict.keys(): ...
    

    до тех пор, пока ограничение на модификацию словаря (либо циклом, либо другим потоком) не нарушается.

  • Добавьте методы к словарям, которые возвращают различные виды итераторы в явном виде:

    for key in dict.iterkeys(): ...
    
    for value in dict.itervalues(): ...
    
    for key, value in dict.iteritems(): ...
    

    Это означает, что for x in dict является сокращением для for x in dict.iterkeys().

В Python 3 dict.iterkeys(), dict.itervalues() и dict.iteritems() больше не поддерживаются. Вместо этого используйте dict.keys(), dict.values() и dict.items().

406
ответ дан 22 November 2019 в 19:47
поделиться

Итерация по dict выполняет итерацию по его ключам в произвольном порядке, как вы можете видеть здесь:

Изменить: (Это больше не так в Python3.6 , но обратите внимание, что это не гарантирует поведения)

>>> d = {'x': 1, 'y': 2, 'z': 3} 
>>> list(d)
['y', 'x', 'z']
>>> d.keys()
['y', 'x', 'z']

Для вашего примера лучше использовать dict.items () :

>>> d.items()
[('y', 2), ('x', 1), ('z', 3)]

Это дает вам список кортежей. Когда вы перебираете их таким образом, каждый кортеж автоматически распаковывается в k и v :

for k,v in d.items():
    print(k, 'corresponds to', v)

Использование k и v как имена переменных при переходе по dict довольно распространены, если тело цикла состоит всего из нескольких строк. Для более сложных циклов может быть хорошей идеей использовать более описательные имена:

for letter, number in d.items():
    print(letter, 'corresponds to', number)

Хорошая идея - выработать привычку использовать строки формата:

for letter, number in d.items():
    print('{0} corresponds to {1}'.format(letter, number))
191
ответ дан 22 November 2019 в 19:47
поделиться

key - это просто переменная.

Для Python2.X:

d = {'x': 1, 'y': 2, 'z': 3} 
for my_var in d:
    print my_var, 'corresponds to', d[my_var]

... или лучше,

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.iteritems():
    print the_key, 'corresponds to', the_value

Для Python3.X:

d = {'x': 1, 'y': 2, 'z': 3} 
for the_key, the_value in d.items():
    print(the_key, 'corresponds to', the_value)
74
ответ дан 22 November 2019 в 19:47
поделиться

При итерации по словарям с помощью for ... in ... -синтаксис, он всегда выполняет итерацию по ключам (значения доступны через dictionary[key]).

Для итерации по парам ключ-значение в Python 2 используйте for k,v in s.iteritems(), а в Python 3 for k,v in s.items().

52
ответ дан 22 November 2019 в 19:47
поделиться

Это очень распространенная идиома зацикливания. in - это оператор. О том, когда следует использовать for key in dict, а когда нужно for key in dict.keys(), смотрите статью Дэвида Гуджера Idiomatic Python (архивная копия).

27
ответ дан 22 November 2019 в 19:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: