#python
#python
Вопрос:
Я пытаюсь найти записи с определенными почтовыми индексами в списке рассылки (формат CSV). Я думал, что это должно сработать, но он ничего не находит, несмотря на то, что я знаю, что искомые почтовые индексы есть.
text = open("during1.txt","r")
a = list(range(93201,93399))
b = list(range(93529,93535))
c = list(range(93601,93899))
d = list(range(95301,95399))
KFCFzip = a b c d
output = open("output.txt","w")
for line in text:
array= line.strip().split(",")
print(array[6][0:5])
if array[6][0:5] in KFCFzip:
#output.write(array)
print("yes")
text.close()
output.close()
Когда я запускаю код, он не находит совпадений, но оператор print над оператором IF выводит значения, которые выглядят так, как будто они должны совпадать, и когда я захожу в оболочку и набираю что-то вроде
93701 in KFCFzip
Это возвращает мне «True:», так что это работает до такой степени. Файл представляет собой просто текст, разделенный запятыми, поэтому я не могу понять, почему он их видит.
В файле данных есть текущие данные, поэтому мне пришлось бы немного изменить его перед публикацией. Мне было интересно, есть ли у кого-нибудь какие-либо идеи, которые не предполагают публикацию самих данных.
Ответ №1:
Потому что array[6][0:5]
это строка. Вы должны преобразовать его в целое число, прежде чем просматривать KFCFzip
список.
for line in text:
array= line.strip().split(",")
print(array[6][0:5])
if int(array[6][0:5]) in KFCFzip:
print("yes")
Другой проблемой этого решения является производительность. range
создает список элементов, поэтому вы собираетесь сравнивать каждый «подозреваемый» почтовый индекс со всеми возможными почтовыми индексами. Временная сложность для этого алгоритма равна, O(n*m)
где n = len(KFCFzip)
а m — количество строк в файле. Лучший способ — создать список диапазонов типа:
KFCFzip = [[93201,93399], [93529,93535], [93601,93899], [95301,95399]]
for line in text:
array= line.strip().split(",")
zip = int(array[6][0:5]))
print(zip)
found = False
for r in KFCFzip:
if zip >= r[0] and zip < r[1]:
found = True
break
if found:
print("yes")
в этом случае вы можете значительно увеличить производительность.
Например, используя ваши данные, у вас были бы 197 5 297 97 = 596
элементы, поэтому для каждой строки вам пришлось бы проводить 596/2 = 298
сравнения в среднем. Но, используя мои алгоритмы, вы получите только 8/2 = 4
сравнения, которые в ~ 75 раз меньше (читаются быстрее).
Комментарии:
1. Будь я проклят за новичка! Я забыл о разнице между int и string. Большое спасибо за предложения.
2. Я работаю над этим. Stack Overflow — отличная ссылка «Помогите, я застрял», которую я стараюсь использовать экономно.
Ответ №2:
Вы должны использовать csv
модуль. То, как вы это делаете, если одно из полей в вашем файле содержит запятую, вы облажались.
Кроме того, вы не должны скрывать встроенные имена, такие как zip
. И присвоение имени вашей переменной array
просто кажется неправильным: во-первых, оно ссылается на list
, а не на array
. Это не одно и то же. Во-вторых, имена переменных должны отражать, на что они ссылаются, а не только тип того, на что они ссылаются.
import csv
KFCFzip = [[93201,93399], [93529,93535], [93601,93899], [95301,95399]]
with open('addresses.csv', 'r') as addressfile:
for address in csv.reader(addressfile):
zipcode = int(address[6][0:5])
for lower, upper in KFCFzip:
if lower <= zipcode < upper:
print('yes')
break
else:
print('no')
Комментарии:
1. я не знал, что zip является встроенным. каждый день изучаю что-то новое (иногда больше одного)
Ответ №3:
Вероятно, это проблема со строками и целыми числами. Попробуйте указать свои array[6][0:5]
или упорядочить свои диапазоны.