Проблемы с циклом Python - PullRequest
       14

Проблемы с циклом Python

2 голосов
/ 15 января 2012

Infile - это генеалогия:

holla   1755
ronaj   1781
asdflæj 1803
axle    1823
einar   1855
baelj   1881
æljlas  1903
jobbi   1923
gurri   1955
kolli   1981
Rounaj  2004

Я хочу распечатывать каждое поколение из infile, а в конце хочу среднее. Здесь я думаю, что моя проблема в том, что line2 выходит за пределы диапазона, когда заканчивается инфилирование:

def main():
    infile = open('infile.txt', 'r')
    line = infile.readline()
    tmpstr = line.split('\t')
    age=[]
    while line !='':
        line2 = infile.readline()
        tmpstr2 = line2.split('\t')
        age.append(int(tmpstr2[1]) - int(tmpstr[1]))
        print age
        tmpstr = tmpstr2
    infile.close()
    print sum(age)*1./len(age)
main()

Поэтому я решил прочитать всю информацию в список, но tmpstr не меняет здесь значения:

def main():
    infile = open('infile.txt', 'r')
    line = infile.readline()
    age=[]
    while line !='':
        tmpstr = line.split('\t')
        age.append(tmpstr[1])
        print age
    infile.close()
    print sum(age)*1./len(age)
main()

Как получилось? Что не так с этими двумя сценариями? Почему я пишу main() два раза? Любые идеи, как эти два могут быть решены?

Спасибо всем, вот как это закончилось:

   def main():
        with open('infile.txt', 'r') as input:
            ages = []
            for line in input:
                data = line.split()
                age = int(data[1])
                ages.append(age)
            gentime = []
            for i in xrange(len(ages)-1):
                print ages[i+1] - ages[i]
                gentime.append(ages[i+1] - ages[i]) 
            print 'average gentime is', sum(gentime)*1./len(gentime)
    main()

Ответы [ 5 ]

1 голос
/ 15 января 2012

Проблема с обоими этими скриптами в том, что ваш цикл while бесконечен.Условие line != '' никогда не будет ложным, если первая строка не пуста.

Вы можете это исправить, но лучше использовать идиому Python:

lastyear = None
ages = []
for line in infile:
    _name, year = line.split('\t')
    year = int(year)
    if lastyear:
        ages.append(year - lastyear)
    lastyear = year
print float(sum(ages))/len(ages)
1 голос
/ 15 января 2012

Вы можете попробовать что-то вроде этого:

if __name__ == "__main__":
    file = open("infile.txt", "r")
    lines = file.readlines()
    gens = [int(x.split('\t')[1]) for line in lines]
    avg = sum(gens)/len(gens)

Первая строка - это собственный вход Python в программу. Это эквивалентно C "int main ()".

Далее, возможно, проще всего настроить списки, если вы прочитаете все строки из файла в список.

Четвертая строка перебирает строки файла, разделяя их на вкладке и извлекая только 2-й элемент (с индексом 1) из нового разделенного списка.

1 голос
/ 15 января 2012

Во втором случае ваш код читает только одну строку из файла.

Что-то попроще, например:

age = []
with open('data.txt', 'rt') as f:
   for line in f:
      vals = line.split('\t')
      age.append(int(vals[1]))

print sum(age) / float(len(age))

создает

1878.54545455
1 голос
/ 15 января 2012

Попробуйте это:

def main():
    with open('infile.txt', 'r') as input:
        ages, n = 0, 0
        for line in input:
            age = int(line.split()[1])
            ages += age
            n += 1
            print age
        print 'average:', float(ages) / n

Некоторые комментарии:

  • Вам не нужно использовать список для накопления чисел, достаточно пары локальных переменных
  • В этом случае целесообразно использовать split() без аргументов. Таким образом, вы будете правильно обрабатывать ввод, когда имя отделяется от числа перед ним пробелами или .
  • Также неплохо использовать синтаксис with для открытия файла и проверки его закрытия после этого

Что касается последней части вашего вопроса: «Почему я пишу main () два раза?» это потому, что в первый раз вы определяете функцию main, а во второй раз вы вызываете it.

1 голос
/ 15 января 2012

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

for line in infile:
    # Perform the rest of your steps here

Вы не захотите использовать цикл while, если у вас нет своего рода счетчика для переключения местоположений индекса (т.е.вы использовали infile.readlines() и хотели использовать цикл while для этого).

...