Я пытаюсь создать массив из данных в списке списков.
ac_name = 'ac'
dat = [['ab=55', 'ac=25', 'db =57', 'dc =44'],
['ab=75','ac =12', 'cg =11', 'pt =95'],
['ab=17', 'ac=62'],
['ab=97', 'aa=501', 'dc=12', 'dd=19']]
Поэтому я хочу получить список, который выглядит так:
ac = ['ac=25','ac=12','ac=62','']
и из этого
ac_values = [25,12,62,'']
В общем, я хочу преобразовать dat в один большой массив.
Я знаю, что это не работает, потому что он проходит через каждый элемент, поэтому на выходе есть много элементов, которые есть в dat.
ac = []
for d in dat:
for c in d:
if ac_name in c:
ac.append(c)
else:
ac.append('')
Как я уже упоминал в комментарии, ваш блок else
находится внутри вложенного цикла, что означает, что для всех элементов в каждом списке, если условие не выполняется, у вас будет пустая строка. Вы можете использовать флаг, чтобы узнать, выполняется if
блок if
в вложенном цикле и добавляет пустую строку к окончательному результату.
In [6]: ac = []
...: for d in dat:
...: flag = True
...: for c in d:
...: if ac_name in c:
...: ac.append(c)
...: flag = False
...: if flag:
...: ac.append('')
...:
In [7]: ac
Out[7]: ['ac=25', 'ac =12', 'ac=62', '']
Но так как это не очень путинский способ решения проблемы, вместо этого вы можете использовать выражения генератора и next()
функцию next()
как показано ниже, чтобы создать словарь из ожидаемого результата. В этом случае вы также можете легко получить доступ к ключам или значениям.
In [19]: result = dict((ind, next((i for i in d if i.startswith(ac_name)), '=').split('=')[1]) for ind, d in enumerate(dat))
In [20]: result
Out[20]: {0: '25', 1: '12', 2: '62', 3: ''}
In [21]: result.keys() # shows number of sub-lists in your original list
Out[21]: dict_keys([0, 1, 2, 3])
In [22]: result.values()
Out[22]: dict_values(['25', '12', '62', ''])
Вы можете использовать itertools.chain
чтобы сгладить список списков. Затем используйте представление списка для фильтрации и разделения элементов по мере необходимости.
from itertools import chain
res = [int(i.split('=')[-1]) for i in chain.from_iterable(dat) \
if i.startswith('ac')]
print(res)
[25, 12, 62]
ac_name = 'ac'
datas = [['ab=55', 'ac=25', 'db =57', 'dc =44'],
['ab=75','ac =12', 'cg =11', 'pt =95'],
['ab=17', 'ac=62'],
['ab=97', 'aa=501', 'dc=12', 'dd=19'],
['ab=55', 'ac=25', 'db =57', 'dc =44'],
['ab=75','ac =12', 'cg =11', 'pt =95'],
['ab=17', 'ac=62'],
['ab=97', 'aa=501', 'dc=12', 'dd=19']]
lst = []
for i,data in enumerate(datas):
for d in data:
if ac_name in d:
lst.append(d.split('=')[-1])
if i == len(lst):
lst.append('')
print(lst)
Выход
['25', '12', '62', '', '25', '12', '62', '']
Попробуй это:
ac_name = 'ac'
ac = []
ac_values = []
for value in dat:
found = False
for item in value:
if ac_name in item:
ac.append(item)
ac_values.append(item.split('=')[-1])
found = True
if not found:
ac.append(' ')
ac_values.append(' ')
print(ac)
print(ac_values)
Выход:
['ac= 25', 'ac = 12', 'ac=62', ' ']
[' 25', ' 12', '62', ' ']
Есть много способов сделать это, как показали люди. Вот один из способов использования списков и функций более высокого порядка:
In [14]: ["" if not kv else kv[0].split('=')[-1].strip() for kv in [filter(lambda x: x.startswith(ac_name), xs) for xs in datas]]
Out[14]: ['25', '12', '62', '']
Если требуется точный ключ "ac", можно также использовать регулярные выражения:
import re
p = re.compile(ac_name + '\s*')
["" if not kv else kv[0].split('=')[-1].strip() for kv in [filter(lambda x: p.match(x), xs) for xs in datas]]
После некоторого озадачивания я нашел возможное решение
Обработайте каждый элемент в каждом подсписке индивидуально: если он содержит "ac", тогда разделите "ac =" часть. Если нет, просто верните пустую строку ''. Затем объедините все элементы в каждом подсписке, используя string.join(). Это вернет список строк с числовой строкой, например, "25" или пустой строкой. Наконец, условно преобразуйте каждую строку в целое число, если это возможно. Else просто возвращает (пустую) строку.
ac = [int(cell_string) if cell_string.isdigit() else cell_string for cell_string in
[''.join([cell.split('=')[1] if ac_name in cell else '' for cell in row]) for row in data]]
Выход:
[25, 12, 62, '']
edit: Если вы хотите расширить его до нескольких имен столбцов, например:
col_name = ['ac', 'dc']
Затем просто расширьте это:
cols = [[int(cell_string) if cell_string.isdigit() else cell_string for cell_string in
[''.join([cell.split('=')[1] if name in cell else '' for cell in row]) for row in data]] for name in col_name]
Выход:
[[25, 12, 62, ''], [44, '', '', 12]]
Это будет работать для любой длины ac_name
:
ac_name = 'ac'
ac = []
ac_values=[]
for i in dat:
found=False
for j in i:
if j[:2]==ac_name:
ac.append(j)
ac_values.append(int(j[len(ac_name)+2:]))
found=True
if not found:
ac.append("")
ac_values.append("")
print(ac)
print(ac_values)