Rm дублирование в понимании списка - PullRequest
0 голосов
/ 09 июля 2011

Ввод - это строка, идея состоит в том, чтобы считать только буквы Az и печатать их в алфавитном порядке с учетом количества появлений.

Как обычно, я продолжал в том же духе, пока не получил рабочий результат, но теперь стремлюсь оптимизировать его, чтобы лучше понять Python, как делать вещи.

def string_lower_as_list(string):
    """
      >>> string_lower_as_list('a bC')
      ['a', ' ', 'b', 'c']
    """
    return list(string.lower())

from sys import argv

letters = [letter for letter in string_lower_as_list(argv[1]) 
            if ord(letter) < 124 and ord(letter) > 96]

uniques = sorted(set(letters))

for let in uniques:
    print let, letters.count(let)
  1. Как убрать дублирование ord (буквы) в понимании списка?
  2. Была бы какая-то польза от использования словаря или кортежа в этом случае, если да, то как?

РЕДАКТИРОВАТЬ Должен был сказать, Python 2.7 на win32

Ответы [ 3 ]

2 голосов
/ 09 июля 2011

Как убрать дублирование орда (буквы) в понимании списка?

Вы можете использовать очень специфичную для Python и несколько волшебную идиому, которая не работает на других языках: if 96 < ord(letter) < 124.

Была бы какая-то польза от использования словаря или кортежа в этом случае, если да, то как?

Вы можете попробовать использовать класс collections.Counter, добавленный в Python 2.7.

P.S. Вам не нужно преобразовывать строку в список, чтобы перебирать ее в понимании списка. Будет работать любая итерация, а строки - итеративные.

P.S. 2. Чтобы получить свойство «эта буква алфавитная», вместо того, чтобы писать в нижнем регистре и сравнивать с диапазоном, просто используйте str.isalpha. Объекты Unicode предоставляют один и тот же метод, который позволяет одному и тому же коду просто работать с текстом на иностранных языках без необходимости знать, какие символы являются «буквами». :)

2 голосов
/ 09 июля 2011

Вы можете сравнивать буквы напрямую, и вам действительно нужно сравнивать только строчные буквы

letters = [letter for letter in string_lower_as_list(argv[1]) 
            if "a" <= letter <= "z"]

Но лучше было бы использовать словарь для подсчета значений.letters.count должен просматривать список каждый раз, когда вы его называете.Но вы уже просматриваете список, чтобы отфильтровать правильные символы, так почему бы не подсчитать их одновременно?

letters = {}

for letter in string_lower_as_list(argv[1]):
    if "a" <= letter <= "z":
        letters[letter] = letters.get(letter, 0) + 1

for letter in sorted(letters):
    print letter, letters[letter] 

Редактировать: Как говорили другие, вы недолжны преобразовать строку в список.Вы можете выполнить итерацию непосредственно: for letter in argv[1].lower().

1 голос
/ 09 июля 2011

Вам не нужно преобразовывать строку в список, строка является итеративной:

letters = {}
for letter in argv[1].lower():
    if "a" <= letter <= "z":
        letters[letter] = letters.get(letter, 0) + 1

for letter in sorted(letters.keys()):
    print letter, letters[letter]
...