Хорошая практика программирования Python для перечисления списков

17

Я довольно новичок в Python и программировании в целом, и мне было интересно, является ли хорошей практикой программирования писать длинные операторы со многими логическими операторами - например, в цикле for.

Например, вот функция, которую я создал, которая получает все гласные от слова и возвращает список, содержащий эти гласные.

def getVowels(word):
    vowel_list = []
    index = 0
    for i in word:
        if i == "a" or i == "e" or i == "i" or i == "o" or i == "u" or i == "A" or i == "E" or i == "I" or i == "O" or i == "U":
            vowel_list.append(word[index])
        index += 1
    return vowel_list

Как вы можете видеть, оператор if получил очень много времени. Это считается хорошим программированием? Если это не так, есть ли лучший способ кодировать эту функцию?     

задан geekkid 07.04.2012 в 15:51
источник
  • Вы должны использовать перечисление вместо счетчика. –  agf 07.04.2012 в 15:59
  • Это хороший вопрос. Не забудьте принять ответ в ближайшие пару дней. –  Marcin 07.04.2012 в 16:10

5 ответов

34

Нет, это не считается хорошей практикой, всегда есть лучшие способы: D

if i.upper() in "AEIOU"

Ниже представлена ​​более короткая версия вашей функции с использованием списков:

def get_vowels(word):
    vowels = "AEIOU"
    return [c for c in word if c.upper() in vowels]
    
ответ дан jamylak 07.04.2012 в 15:54
источник
  • Спасибо. Я не знал, что могу использовать «in» для строк, я думал, что могу использовать его только для списков. Но поскольку строки ведут себя почти так же, как списки, я должен был знать это .d Спасибо всем. –  geekkid 07.04.2012 в 16:02
  • Да, есть много ярлыков: D –  jamylak 07.04.2012 в 16:03
  • @geekkid Способность сжимать ваш код до этого ответа в значительной степени зависит от того, что такое python - он действительно обеспечивает краткое, не повторяющееся кодирование. –  Marcin 07.04.2012 в 16:09
  • в работах для любого итерабельного –  Simon 07.04.2012 в 17:34
  • Как и младший nitpick, Python имеет тенденцию использовать underscored_names, например get_vowels. –  Peter C 07.04.2012 в 21:14
Показать остальные комментарии
4

Вероятно, лучше использовать наборы:

VOWELS = set('aeiouAUIOU')

def get_vowels(word):
    return [c for c in word if c in VOWELS]

или, более geeky:

def get_vowels(word):
    return filter(VOWELS.__contains__, word)

(Но первый подход является наиболее читаемым и, как таковой, более pythonic.Кроме того, вторая функция будет возвращать генератор, а не список в Python 3.)

EDIT сравнение производительности c in list vs c in set :

import timeit

VOWELS = 'aeiouAEIOU'
VOWSET = set(VOWELS)
SAMPLE = 'asflasrjoperugASDFAROUAoarfpeoriugargagadropgue'

def get_vowels(word, vowels):
    return [c for c in word if c in vowels]

print timeit.timeit('get_vowels(SAMPLE, VOWELS)', 
                    'from __main__ import VOWELS, SAMPLE, get_vowels') 
# ^ prints 10.0739870071
print timeit.timeit('get_vowels(SAMPLE, VOWSET)', 
                    'from __main__ import VOWSET, SAMPLE, get_vowels') 
# ^ prints 9.43965697289
    
ответ дан bereal 07.04.2012 в 17:05
источник
  • Ваша последняя функция не дает гласных в слове, она просто говорит «Правда» или «ложь» –  jamylak 07.04.2012 в 17:07
  • @jamylak о стыд на мне. Спасибо, удалил. –  bereal 07.04.2012 в 17:09
  • Является ли использование наборов быстрее? Потому что VOWELS = 'aeiouAUIOU' также работает. –  Akavall 07.04.2012 в 17:18
  • @Akavall да, это немного быстрее, обновляется с выходом timeit. Для последовательностей длиннее, чем разница aeiouAEIOU будет более значимой. –  bereal 07.04.2012 в 17:37
  • Набор содержит среднее время ожидания, список - линейное время. Количество персонажей здесь крошечное, поэтому он практически не отличается. –  Ali Afshar 07.04.2012 в 18:17
1

if совпадает с:

if i in "aeiouAEIOU"

В основном вы проверяете член в наборе.

    
ответ дан Keith 07.04.2012 в 15:55
источник
  • @agf Они эквивалентны, если предположить, что слово является строкой –  Ismail Badawi 07.04.2012 в 15:57
1

Я думаю, что длинные заявления сложнее понять, чем короткие. Почти всегда есть способ сделать то же самое с более короткими утверждениями. В вашем случае вы можете упростить, если так:

def getVowels(word):
    vowel_list = []
    for i in word:
        if i in "aeiouAEIOU":
            vowel_list.append(i)
    return vowel_list

, поскольку Python позволяет вам использовать оператор «in» для поиска одной строки внутри другой.

Но Python также позволяет использовать списки, упрощающие циклы:

def getVowels(word):
    return [i for i in word if i in "aeiouAEIOU"]
    
ответ дан Vaughn Cato 07.04.2012 в 15:56
источник
1

Как

set('aeiouAUIOU') & set(word)
    
ответ дан Ali Afshar 07.04.2012 в 18:20
источник
  • Ох, довольно ... Кроме того, что скремблирует буквы и не сохраняет дубликаты. –  Christian Mann 08.04.2012 в 01:38
  • Да, и да, но слишком красиво, чтобы пропустить. –  Ali Afshar 08.04.2012 в 03:12