Проверка, являются ли две строки перестановками друг друга в Python - PullRequest
18 голосов
/ 28 декабря 2008

Я проверяю, являются ли две строки a и b перестановками друг друга, и мне интересно, каков идеальный способ сделать это в Python. Из дзен Python: «Должен быть один - и желательно только один - очевидный способ сделать это», но я вижу, что есть как минимум два способа:

sorted(a) == sorted(b)

и

all(a.count(char) == b.count(char) for char in a)

но первый медленнее, когда (например) первый символ a нигде не находится в b, а второй медленнее, когда они на самом деле являются перестановками.

Есть ли лучший (или в смысле более Pythonic, или в смысле более быстрый в среднем) способ сделать это? Или я должен просто выбрать один из этих двух, в зависимости от того, какая ситуация, по моему мнению, наиболее распространена?

Ответы [ 21 ]

0 голосов
/ 29 декабря 2008

Эта версия быстрее, чем любые представленные примеры, за исключением того, что она на 20% медленнее, чем sorted(x) == sorted(y) для коротких строк. Это зависит от вариантов использования, но обычно увеличение производительности на 20% недостаточно, чтобы оправдать усложнение кода при использовании другой версии для коротких и длинных строк (как в ответе @ patros).

Он не использует len, поэтому он принимает любые итерации, поэтому он работает даже для данных, которые не помещаются в памяти, например, учитывая два больших текстовых файла с множеством повторяющихся строк, он отвечает, имеют ли файлы одинаковые строки (строки можно в любом порядке).

def isanagram(iterable1, iterable2):
    d = {}
    get = d.get
    for c in iterable1:
        d[c] = get(c, 0) + 1
    try:
        for c in iterable2:
            d[c] -= 1
        return not any(d.itervalues())
    except KeyError:
        return False

Неясно, почему эта версия быстрее, чем defaultdict (@ namin's) для большой iterable1 (проверено на тезаурусе 25 МБ).

Если мы заменим get в цикле на try: ... except KeyError, тогда он будет работать в 2 раза медленнее для коротких строк, т. Е. При наличии нескольких дубликатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...