#python #csv #dictionary #rows
#python #csv #словарь #строки
Вопрос:
Я все еще новичок и застрял в этом случае.
У меня есть файл csv, который похож на следующий.
import csv
csvpath = "C:/Test/test.csv"
with open(csvpath) as f:
csv = csv.DictReader(f)
for row in csv:
print(row)
и вывод:
{'NAME': 'John', 'NICKNAME': 'Big John', 'COUNTRY': 'Canada', 'CITY': 'Toronto'}
{'NAME': 'David', 'NICKNAME': 'Small Jogn', 'COUNTRY': 'Canada', 'CITY': 'Toronto'}
{'NAME': 'Alan', 'NICKNAME': 'The Bull', 'COUNTRY': 'England', 'CITY': 'London'}
{'NAME': 'Ethan', 'NICKNAME': 'The Hawk', 'COUNTRY': 'England', 'CITY': 'London'}
{'NAME': 'Ivan', 'NICKNAME': 'The Russian', 'COUNTRY': 'Russia', 'CITY': 'Moscow'}
{'NAME': 'Boris', 'NICKNAME': 'The Bear', 'COUNTRY': 'Russia', 'CITY': 'Moscow'}
Возможно ли сначала напечатать только те строки, в которых есть страна Канада. Затем я хочу, чтобы еще один цикл печатал строки со странами Англия и еще один для России. Однако страна будет постоянно редактироваться, поэтому она не будет одинаковой, и каждый день в этом списке могут быть разные страны и количество стран. Поэтому в основном мне нужно печатать в разных циклах for отдельно строки с одинаковыми странами.
Комментарии:
1. Это не то, как выглядит файл csv.
2. Да, это csv, который можно прочитать как словарь при использовании
with open(csvpath) as f: csv = csv.DictReader(f)
3. Вам действительно нужно печатать в «разных циклах» или вы хотите распечатать строки в файле, упорядоченном по стране?
4. @snakecharmerb да, в разных циклах. Первый цикл для печати только строк из одной страны. 2-й цикл для печати из другой страны и так далее.
Ответ №1:
Приведенный ниже код группирует данные по странам: (на основе структуры данных в вопросе)
from collections import defaultdict
data = [{'NAME': 'John', 'NICKNAME': 'Big John', 'COUNTRY': 'Canada', 'CITY': 'Toronto'},
{'NAME': 'David', 'NICKNAME': 'Small Jogn', 'COUNTRY': 'Canada', 'CITY': 'Toronto'},
{'NAME': 'Alan', 'NICKNAME': 'The Bull', 'COUNTRY': 'England', 'CITY': 'London'},
{'NAME': 'Ethan', 'NICKNAME': 'The Hawk', 'COUNTRY': 'England', 'CITY': 'London'},
{'NAME': 'Ivan', 'NICKNAME': 'The Russian', 'COUNTRY': 'Russia', 'CITY': 'Moscow'},
{'NAME': 'Boris', 'NICKNAME': 'The Bear', 'COUNTRY': 'Russia', 'CITY': 'Moscow'}]
data_by_country = defaultdict(list)
for entry in data:
data_by_country[entry['COUNTRY']].append(entry)
for country, info_lst in data_by_country.items():
print(country)
for info in info_lst:
print(f't {info}')
вывод
Canada
{'NAME': 'John', 'NICKNAME': 'Big John', 'COUNTRY': 'Canada', 'CITY': 'Toronto'}
{'NAME': 'David', 'NICKNAME': 'Small Jogn', 'COUNTRY': 'Canada', 'CITY': 'Toronto'}
England
{'NAME': 'Alan', 'NICKNAME': 'The Bull', 'COUNTRY': 'England', 'CITY': 'London'}
{'NAME': 'Ethan', 'NICKNAME': 'The Hawk', 'COUNTRY': 'England', 'CITY': 'London'}
Russia
{'NAME': 'Ivan', 'NICKNAME': 'The Russian', 'COUNTRY': 'Russia', 'CITY': 'Moscow'}
{'NAME': 'Boris', 'NICKNAME': 'The Bear', 'COUNTRY': 'Russia', 'CITY': 'Moscow'}
Комментарии:
1. Спасибо, это самый близкий ответ на мой вопрос, но можно ли читать не из словаря, а из csv, как я писал выше, используя
with open(csvpath) as f: csv = csv.DictReader(f`)
?2. @bbfl Попробуйте прочитать csv и создать dict. Это хороший опыт для вас.
Ответ №2:
когда они все вместе в массиве.
def print_countries(array,countryname):
print("results for: ", countryname)
for item in array:
if item['COUNTRY'] == countryname:
print(item)
сделал это функцией. Если вы хотите напечатать каждую страну в файле CSV, я бы создал массив с каждым именем.
def get_countrynames(array):
countryname_list = []
for row in array:
if row['COUNTRY'] not in countryname_list:
countryname_list.append(row['COUNTRY'])
return countryname_list
with open(csvpath) as f:
csv = csv.DictReader(f)
names = get_countrynames(csv)
for country in names:
print_countries(csv,country)
надеюсь, это сработает, не проверял сам
Комментарии:
1. Спасибо, но, как я уже сказал, страны будут меняться каждый день в файле csv, поэтому в следующий раз Канады может не быть в файле csv.
Ответ №3:
Выбор элементов из коллекции на основе некоторого критерия называется фильтрацией.
Python предоставляет встроенную функцию фильтра для этого, или вы можете использовать понимание списка или выражение генератора для достижения того же результата.
Понимание списка выполняется быстрее filter
и считается более «питоническим», но я нахожу filter
, что иногда код становится проще для понимания. Выражение генератора синтаксически похоже на понимание списка, но использует меньше памяти (и может быть повторено только один раз).
Приведенная ниже функция показывает, как использовать все три опции. Он принимает открытый файл и список названий стран (в виде строк) в качестве своих аргументов и выводит строки, найденные для каждой страны.
import csv
def print_rows(file, countries):
reader = csv.DictReader(file)
# Make a list of all the rows so we can loop over them more than once.
rows = list(reader)
for country in countries:
print('Printing rows for', country)
# Filter the rows by country.
# Using the filter built-in function.
filtered_rows = filter(lambda row: row['COUNTRY'] == country, rows)
# List comprehension.
# filtered_rows = [row for row in rows if row['COUNTRY'] == country]
# Generator expression.
# filtered_rows = (row for row in rows if row['COUNTRY'] == country)
for row in filtered_rows:
print(row)
print()
return
countries = ['Canada', 'Russia']
csvpath = "C:/Test/test.csv"
with open(csvpath) as f:
csv = csv.DictReader(f)
print_rows(f, countries)
Вывод:
Printing rows for Canada
{'NAME': 'John', 'NICKNAME': 'Big John', 'COUNTRY': 'Canada', 'CITY': 'Toronto'}
{'NAME': 'David', 'NICKNAME': 'Small Jogn', 'COUNTRY': 'Canada', 'CITY': 'Toronto'}
Printing rows for Russia
{'NAME': 'Ivan', 'NICKNAME': 'The Russian', 'COUNTRY': 'Russia', 'CITY': 'Moscow'}
{'NAME': 'Boris', 'NICKNAME': 'The Bear', 'COUNTRY': 'Russia', 'CITY': 'Moscow'}