Я бы использовал 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
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())
.
Дело не в том, что 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()
.
Итерация по 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))
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)
При итерации по словарям с помощью for ... in ...
-синтаксис, он всегда выполняет итерацию по ключам (значения доступны через dictionary[key]
).
Для итерации по парам ключ-значение в Python 2 используйте for k,v in s.iteritems()
, а в Python 3 for k,v in s.items()
.
Это очень распространенная идиома зацикливания. in
- это оператор. О том, когда следует использовать for key in dict
, а когда нужно for key in dict.keys()
, смотрите статью Дэвида Гуджера Idiomatic Python (архивная копия).