#python #regex
#python #регулярное выражение
Вопрос:
Мне нужно найти город с наибольшим населением, используя регулярные выражения, данные представлены таким образом:
data = ["id,name,poppulation,is_capital",
"3024,eu_kyiv,24834,y",
"3025,eu_volynia,20231,n",
"3026,eu_galych,23745,n",
"4892,me_medina,18038,n",
"4401,af_cairo,18946,y",
"4700,me_tabriz,13421,n",
"4899,me_bagdad,22723,y",
"6600,af_zulu,09720,n"]
Я делал это до сих пор:
def max_population(data):
lst = []
for items in data:
a = re.findall(r',S _S ,[0-9] ', items)
lst = [[b for b in i.split(',') if b] for i in a]
return max(lst, key=lambda x:int(x[1]))
Но функция должна возвращать (str, int) кортеж, возможно ли изменить мой код таким образом, чтобы он возвращал кортеж без повторения списка еще раз?
Ответ №1:
Все ваши строки разделяются запятой. Вы можете получить максимальное значение с помощью split и проверить, является ли третье значение цифрой и больше первого значения кортежа.
Если это так, установите его как новое наибольшее значение.
def max_population(data):
result = None
for s in data:
parts = s.split(",")
if not parts[2].isdigit():
continue
tup = (parts[1], int(parts[2]))
if result is None or tup[1] > result[1]:
result = tup
return result
print(max_population(items))
Вывод
('eu_kyiv', 24834)
Ответ №2:
Следующая длинная строка дает желаемый результат (str, int) tuple
:
def max_population(data):
p=max([(re.findall(r"(w*),d*,w$",i)[0],int(re.findall(r"(d*),w$",i)[0])) for n,i in enumerate(data) if n>0],key=lambda x:int(x[1]) )
return p
в этой строке enumerate(data)
и n>0
использовались для пропуска заголовка "id,name,poppulation,is_capital"
. Но если data
нет заголовка, строка будет:
def max_population(data):
p=max([(re.findall(r"(w*),d*,w$",i)[0],int(re.findall(r"(d*),w$",i)[0])) for i in data],key=lambda x:int(x[1]) )
return p
Результат для обоих ('eu_kyiv', 24834)
Ответ №3:
Создайте список кортежей вместо списка списков.
import re
data = ["id,name,poppulation,is_capital",
"3024,eu_kyiv,24834,y",
"3025,eu_volynia,20231,n",
"3026,eu_galych,23745,n",
"4892,me_medina,18038,n",
"4401,af_cairo,18946,y",
"4700,me_tabriz,13421,n",
"4899,me_bagdad,22723,y",
"6600,af_zulu,09720,n"]
def max_population(data):
lst = []
for items in data:
a = re.findall(r',S _S ,[0-9] ', items)
lst = [tuple(b for b in i.split(',') if b) for i in a]
return max(lst, key=lambda x:int(x[1]))
print(max_population(data))
Ответ №4:
Вы могли бы создать функцию сопоставления для сопоставления типов с данными и использовать эту operator.itemgetter
функцию в качестве ключа в max
:
from operator import itemgetter
def f(row):
# Use a tuple of types to cast str to the desired type
types = (str, int)
# slice here to get the city and population values
return tuple(t(val) for t, val in zip(types, row.split(',')[1:3]))
# Have max consume a map on the data excluding the
# header row (hence the slice)
max(map(f, data[1:]), key=itemgetter(1))
('eu_kyiv', 24834)