Ітерація кожного символу в рядку за допомогою Python


517

У мові C ++ я можу повторити std::stringподібне:

std::string str = "Hello World!";

for (int i = 0; i < str.length(); ++i)
{
    std::cout << str[i] << std::endl;
}

Як повторити рядок у Python?

Відповіді:


441

Як зазначав Йоханнес,

for c in "string":
    #do something with c

Ви можете повторити майже все, що в python, використовуючи for loopконструкцію,

наприклад, open("file.txt")повертає об’єкт файлу (і відкриває файл), ітерація над ним повторює рядки у цьому файлі

with open(filename) as f:
    for line in f:
        # do something with line

Якщо це здається магічним, добре, це все-таки є, але ідея за цим дійсно проста.

Існує простий протокол ітератора, який можна застосувати до будь-якого виду об’єктів, щоб змусити forцикл працювати над ним.

Просто застосуйте ітератор, який визначає next()метод, і __iter__реалізуйте метод на класі, щоб зробити його ітерабельним. ( __iter__звичайно, слід повернути об’єкт ітератора, тобто об'єкт, який визначає next())

Дивіться офіційну документацію


14
Як зауваження, зворотна ітерація архівується за допомогою: for c in
reversed

З якої частини документації ви знаєте, що рядок - це ітератор?
winklerrr

реж () а string..you з см ITER атрибут.
shadow0359

312

Якщо вам потрібен доступ до індексу під час ітерації через рядок, використовуйте enumerate():

>>> for i, c in enumerate('test'):
...     print i, c
... 
0 t
1 e
2 s
3 t

9
Про поради: вона починається з нуля. Якщо вам необхідно запустити його з одного: 1 t, 2 e, 3 s, 4 tвикористовуйте параметр «Пуск»:for i, c in enumerate('test', start=1)
Меса

90

Ще простіше:

for c in "test":
    print c

Я новачок у Python. Чомусь це не компілюється в моєму середовищі, і мені довелося поставити c в дужки, щоб воно працювало: for c in "test": print (c) чому?
Мауро Ванетті

7
@MauroVanetti це майже напевно, тому що ти використовуєш Python 3, і коли я відповів на запитання, AFAIK був лише Python 2.
Johannes Weiss

37

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

i = 0
while i < len(str):
    print str[i]
    i += 1

Але знову ж таки, навіщо це робити, коли рядки за своєю суттю ітерабельні?

for i in str:
    print i

6
Замість першого циклу while, ви можете зробити: for i in range (len (str)): print (str [i]) Що на мій погляд, краще, ніж керувати лічильником самостійно. Ще краще - відповідь Маркога за допомогою перерахування.
аїхам

1
Це може бути засноване на тому, що я так довго використовував C, але я майже завжди закінчую цей метод C-ish. Наприклад, у мене є файл, на якому розкидані чотиризначні числа, всі починаються з 0. Тому мені потрібно знайти "0" і захопити його та наступні 3 символи, і рухатися далі, не дублюючи число, якщо є ще 0 за ним. Жоден із методів "для c в str" або "для i, c в перерахуванні (str)" не працює, тому що мені потрібен контроль над індексом. Я впевнений, що регулярний вираз був би набагато кращим.
gkimsey

1
for i in range(len(...))є зло. У python 2.x range()створює список, тож за дуже великої довжини ви можете виділити дуже великий блок пам'яті. Як мінімум використання xrange()в тих випадках. Крім того, повторне індексування одного і того ж рядка набагато повільніше, ніж повторення безпосередньо над рядком. Якщо вам потрібен індекс, використовуйте enumerate().
izak

6

Ну ви також можете зробити щось цікаве, як це, і виконувати свою роботу, використовуючи для циклу

#suppose you have variable name
name = "Mr.Suryaa"
for index in range ( len ( name ) ):
    print ( name[index] ) #just like c and c++ 

Відповідь є

Містер . S уря

Однак оскільки range () створює список значень, що є послідовністю, то ви можете безпосередньо використовувати ім'я

for e in name:
    print(e)

Це також дає такий же результат, а також виглядає краще і працює з будь-якою послідовністю, як список, кортеж та словник.

Ми використовували вбудовані функції (BIF в Python Community)

1) діапазон () - діапазон () BIF використовується для створення індексів Приклад

for i in range ( 5 ) :
can produce 0 , 1 , 2 , 3 , 4

2) len () - len () BIF використовується для з'ясування довжини заданого рядка


4

Якщо ви хочете скористатися більш функціональним підходом до ітерації над рядком (можливо, щоб якось перетворити його), ви можете розділити рядок на символи, застосувати функцію до кожного, а потім приєднати отриманий список символів назад до рядка.

Рядок є по суті списком символів, отже, «карта» буде повторюватися над рядком - як другий аргумент - застосовуючи функцію - перший аргумент - до кожного.

Наприклад, тут я використовую простий лямбда-підхід, оскільки все, що я хочу зробити, - це тривіальна модифікація символу: тут збільшується значення кожного символу:

>>> ''.join(map(lambda x: chr(ord(x)+1), "HAL"))
'IBM'

або загальніше:

>>> ''.join(map(my_function, my_string))

де my_function приймає значення char та повертає char значення.


2

Тут використовується кілька відповідей range. xrangeяк правило, краще, оскільки він повертає генератор, а не повністю інстальований список. Там, де пам'ять та / або ітерабелі широко різної довжини можуть бути проблемою, xrangeє вищим.


1
зауважте, що це стосується лише Python 2, який, сподіваємось, скорочується меншість
Сем Мейсон

0

Якщо ви коли-небудь стикаєтеся з ситуацією, коли вам потрібно get the next char of the word using __next__(), не забудьте створити string_iteratorі повторити його, а не йогоoriginal string (it does not have the __next__() method)

У цьому прикладі, коли я знаходжу char = [я продовжую шукати наступне слово, поки не знаходжу ], тому мені потрібно використовувати __next__

тут цикл для рядка не допоможе

myString = "'string' 4 '['RP0', 'LC0']' '[3, 4]' '[3, '4']'"
processedInput = ""
word_iterator = myString.__iter__()
for idx, char in enumerate(word_iterator):
    if char == "'":
        continue

    processedInput+=char

    if char == '[':
        next_char=word_iterator.__next__()
        while(next_char != "]"):
          processedInput+=next_char
          next_char=word_iterator.__next__()
        else:
          processedInput+=next_char
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.