Не удается получить следующую строку, используя next() в цикле (python)

Я пытаюсь написать код, который перебирает текстовый файл и получает только те строки, которые я хочу распечатать.

текстовый файл должен выглядеть так:

mimi
passwordmimi
mimi johnson
somejob
joji
passwordjoji
jojo
somejob
john
passwordjohn
jonathan
somejob
....

и так далее. этот текстовый файл содержит в основном информацию о пользователе (для входа в систему). Мне нужно распечатать имя пользователя каждого и его настоящее имя (например: Мими и Мими Джонсон.) И только те. Я не хочу, чтобы информация о текущем пользователе распечатывалась (в этом примере: joji)

вот мой код:

username="joji"

file=open("username.txt","r") 
x=file.readlines()

x=[item.rstrip('\n') for item in x]

x=iter(x)

for line in x:
      if line==username:
              next(x,None)
              next(x,None)
              next(x,None)
      else:
              print line + " username"    ****username should print out. ex:mimi or john
              next(x,None)
              print line +" real name   ****real name should print out. ex: mimi johnson or jonathan

по какой-то причине, когда я запускаю эту программу и распечатываю второй ****, который я поставил, он дважды печатает имя пользователя. (так например:

mimi username
mimi real name
mimi johnson username
mimi johnson real name
john username
john real name
jonathan username
jonathan real name
....

почему это? он должен распечатать

mimi username
mimi johnson real name
john username
jonathan realname 
...

если бы кто-то мог мне помочь, я был бы очень благодарен, я не получаю python. Я также открыт для любых других предложений, чтобы сделать это.

РЕДАКТИРОВАТЬ ::: я попытался внести изменения с предложением, это результат:

новый блок кода:

else: 
      print line + "username" 
      line =next(x,None)
      print line

это новый результат:

 mimi username
 passmimi real name
 mimi johnson username
 somejob real name
 john username
 passjohn real name
 jonathan username
 somejob real name(***im assuming this one is from john's job)

:/ он не делает то, что должен


person harekuin    schedule 15.08.2016    source источник
comment
Вызов next() не изменяет значение line.   -  person Code-Apprentice    schedule 16.08.2016
comment
это не так? то что было бы лучшим способом   -  person harekuin    schedule 16.08.2016
comment
Я думаю, вам нужно зафиксировать возвращаемое значение next в этом случае. например line = next(x)   -  person Paul Rooney    schedule 16.08.2016
comment
я пытался это сделать (просто добавляя строку = next(x) сразу после первого вывода имени пользователя), но это дает мне не то, что я хочу? как будто он дает мне строку, которую он пропускает. и если я добавлю дополнительный метод next(), чтобы получить нужную мне строку, это испортит всю итерацию. есть ли лучший способ перебирать и пропускать строки, которые мне не нужны, кроме следующих? я открыт для предложений   -  person harekuin    schedule 16.08.2016
comment
он дает мне строку, которую он пропускает Что вы имеете в виду под этим? Можете ли вы отредактировать свой вопрос с предложенными изменениями и показать результат так же, как в исходном вопросе?   -  person Code-Apprentice    schedule 16.08.2016
comment
хорошо, дай мне секунду   -  person harekuin    schedule 16.08.2016
comment
хорошо, это сделано. как вы можете видеть, это дает мне строку, предшествующую тому, что я хочу   -  person harekuin    schedule 16.08.2016
comment
Вы хотите пропустить пароли и задания? Если это так, вам просто нужно позвонить next() в соответствующее время, чтобы сделать это.   -  person Code-Apprentice    schedule 16.08.2016
comment
Кстати, x=iter(x), вероятно, не очень хорошая идея, потому что вы используете одну и ту же переменную для двух разных целей. Вы должны создать новую переменную здесь i = iter(x). Кроме того, x и i — ужасные имена переменных. Вы должны использовать более описательные имена.   -  person Code-Apprentice    schedule 16.08.2016
comment
Ну, в том-то и дело, что цикл for повторяется уже один раз, и я больше не знаю, где я должен разместить next(). Я поставил 3 внутри оператора if, чтобы передать пользователя, которого я не хочу. а затем цикл for повторяется один раз. а затем я распечатываю имя пользователя, которое хочу. используйте next(), чтобы пропустить пароль. n затем я хотел распечатать настоящее имя. но вы говорите мне, что next() не меняет саму строку. если я добавлю дополнительный next(), чтобы сделать line=next(), чтобы получить настоящее имя, это испортит весь цикл:/   -  person harekuin    schedule 16.08.2016
comment
я должен помнить об этом (для имен переменных), это просто мой способ ускорить код, потому что я делал это только для себя, извините!   -  person harekuin    schedule 16.08.2016
comment
есть ли лучший способ перебрать цикл и пропустить то, что я не хочу, так, как я это сделал? все в порядке, если я не могу использовать next(). я просто не знаю, как это сделать.   -  person harekuin    schedule 16.08.2016
comment
Я предлагаю вам сделать резервную копию подальше от компьютера. Возьмите карандаш и лист бумаги и напишите по-английски шаги, необходимые для решения этой проблемы. Я думаю, это поможет вам увидеть изменения, которые вам нужно сделать.   -  person Code-Apprentice    schedule 16.08.2016


Ответы (1)


Я бы рекомендовал использовать регулярное выражение для анализа этого файла:

import re

# regex expression to parse the file as you provided it
# you could access the parseddata as a dict using the 
# keys "username", "password", "real_name" and "job"
ex = "\n*(?P<username>.+)\n(?P<password>.+)\n(?P<real_name>.+)\n(?P<job>.+)[\n\$]"

with open("usernames.txt", 'r') as users:
    matches = re.finditer(ex, users.read())
    for match in matches:
        user = match.groupdict()  # user is a dict

        # print username and real name
        print(user['username'], "username", user['real_name'], "real name")

Редактировать: я решил, что регулярное выражение здесь не нужно, так как формат этого файла довольно прост. Итак, вот то же самое без использования регулярных выражений.

def parse(usersfile):
    # strip line break characters
    lines = (line.rstrip('\n') for line in usersfile)

    # keys to be used in the dictionnary
    keys = ('username', 'password', 'real_name', 'job')

    while True:
        # build the user dictionnary with the keys above
        user = {key: line for key, line in zip(keys, lines)}

        # yield user if all the keys are in the dict
        if len(user) == len(keys):
            yield user
        else:  # stop the loop
            break

with open("usernames.txt", 'r') as usersfile:
    for user in parse(usersfile):
        # print username and real name
        print(user['username'], "username", user['real_name'], "real name")
person odrling    schedule 15.08.2016
comment
это предполагает, что у меня есть имя пользователя и пароль перед элементами в списке? (как в текстовом файле) - person harekuin; 16.08.2016
comment
Предполагается, что первая строка — это имя пользователя, вторая — пароль, третья — настоящее имя, а четвертая — задание. Если это то, что вы имеете в виду, то да. ;) - person odrling; 16.08.2016
comment
омг я не могу читать. большое спасибо, я собираюсь зациклить все это и учиться на этом коде! - person harekuin; 16.08.2016
comment
Я попытался запустить ваш код, чтобы увидеть результат и то, как он работает, и он выдал мне ошибку: Traceback (последний последний вызов): Файл make1.py, строка 9, в ‹module› соответствует = re.finditer(ex, users ) Файл /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py, строка 190, в finditer return _compile(шаблон, флаги).finditer(string) TypeError: ожидаемая строка или буфер - person harekuin; 16.08.2016
comment
да, я только что заметил, что забыл прочитать () файл, отредактировав свой ответ - person odrling; 16.08.2016
comment
извините, я не хочу беспокоить, но не могли бы вы объяснить мне шаблон (ex), который вы написали ›‹'' не знаете, что делает ?P и [\n\$]. спасибо! - person harekuin; 16.08.2016
comment
(?P‹...›...) — это именованный шаблон, который находится между ‹ и › — это имя шаблона, который будет доступен в словаре, который вы получаете при вызове groupdict(). [\n\$] соответствует либо разрыву строки '\n', либо концу строки '\$' - person odrling; 16.08.2016
comment
возможно, это тоже может помочь, оно объясняет все в этом выражении - person odrling; 16.08.2016
comment
о, хорошо, так что? P вроде как объявляет шаблон? также почему вы использовали read(), а не readline()? я пытался использовать readline() просто чтобы посмотреть, и это не работает - person harekuin; 16.08.2016
comment
ооо спасибо за сайт! последний вопрос: нужен ли .* в конце ‹›, потому что я хочу, чтобы он продолжал захватывать остальные совпадения? - person harekuin; 16.08.2016
comment
ТАКЖЕ: хешируйте свои пароли. Никогда не храните пароли в открытом виде. - person Henry Prickett-Morgan; 16.08.2016
comment
read() читает весь файл напрямую, что необходимо для re. Вы имеете в виду, что он не возвращает все совпадения? - person odrling; 16.08.2016
comment
Я только что добавил в свой ответ решение, которое не использует регулярное выражение, оно делает то же самое, что и решение регулярного выражения с использованием генератора (функция parse) - person odrling; 16.08.2016