Список строк, хочу разбить их на два списка - PullRequest
2 голосов
/ 24 апреля 2019

Я пытаюсь разделить список строк с именами файлов в каталоге.Файлы были сгенерированы в парах.Один оригинальный, а второй модифицированный.Таким образом, список выглядит примерно так:

files = ['data1', 'data2', 'data3', 'data1-m', 'data2-m', 'data3-m']

, но все перемешано.
Я хочу создать два списка, где индексы соответствуют друг другу, например:

original_files = ['data1','data2','data3']
modified_files = ['data1-m','data2-m','data3-m']

В настоящее время у меня есть:

noised_files = [x for x in files if 'm' in x]
original_files = [x for x in files if not 'm' in x]

, который разделяет список, но не попарно, где я хотел бы получить:

>original_files[0] = 'data1'
>noised_files[0] = 'data1-m'

Спасибо.

Ответы [ 6 ]

3 голосов
/ 24 апреля 2019

Использование list-comprehension с str.endswith() и sorted():

files = ['data3', 'data1', 'data2', 'data2-m', 'data3-m', 'data1-m']

files = sorted(files)
print([x for x in files if x.endswith('m')])
print([x for x in files if not x.endswith('m')])

EDIT

Что также можно записать как:

noised_files = [x for x in files if x.endswith('m')]
original_files = [x for x in files if x not in noised_files]

print(original_files[0])                 # data1
print(noised_files[0])                   # data1-m

РЕДАКТИРОВАТЬ 2 :

Использование filter():

print(list(filter(lambda x: x.endswith('m'), files)))
print(list(filter(lambda x: not x.endswith('m'), files)))

OUTPUT

['data1-m', 'data2-m', 'data3-m']
['data1', 'data2', 'data3']
2 голосов
/ 24 апреля 2019

Если вы можете гарантировать, что все партнеры присутствуют в исходном списке, вы можете просто «игнорировать» варианты -m и «заново» добавить их в новый список.

pairs = [(x, "{}-m".format(x)) for x in files if not x.endswith("-m")]

Затем вы можете разархивировать pairs, чтобы получить два соответствующих списка, если это необходимо:

original_files, modified_files = zip(*pairs)

При этом сохраняется порядок исходных файлов, а также переупорядочиваются измененные файлы для соответствия.

1 голос
/ 24 апреля 2019

Один из способов - сгруппировать строки в списке, используя itertools.groupby и zip.Таким образом вы гарантируете, что элементы, разделяющие начальную подстроку в обоих списках, имеют совпадающие индексы:

from itertools import groupby
l = [list(v) for _,v in groupby(sorted(files), key=lambda x: x.rstrip('-m'))]
original_files, noised_files= list(zip(*l))

, что дает:

print(original_files)
# ('data1', 'data2', 'data3')

print(noised_files)
# ('data1-m', 'data2-m', 'data3-m')
0 голосов
/ 24 апреля 2019

Если часть имени, обозначающая измененные файлы, всегда находится в одном и том же месте в имени, вы можете просто отсортировать полученные списки:

files = ['data1', 'data2', 'data3', 'data3-m', 'data1-m', 'data3-m']

# we could use list comprehensions, but this way, we only iterate once on files. 
original_files = []
modified_files = []
for f in files:  
    if f.endswith('-m'):
        modified_files.append(f)
    else:
        original_files.append(f)

original_files.sort()
modified_files.sort()

Выход:

for i in range(len(original_files)):
    print(original_files[i], modified_files[i])

# data1 data1-m
# data2 data3-m
# data3 data3-m
0 голосов
/ 24 апреля 2019

Я думаю, что было бы безопаснее использовать регулярные выражения.Ваши файлы могут содержать в имени букву m, поэтому вы ищете файлы, заканчивающиеся на -m.Я рекомендую что-то вроде этого:

import re

files = ['data1', 'data2', 'data3', 'data1-m', 'data2-m', 'data3-m']

original_files = []
modified_files = []

for file in files:
    if (re.search("-m$", file)):
        modified_files.append(file)
    else:
        original_files.append(file)

print(original_files, modified_files)

Вы можете отсортировать списки в конце, перед печатью или написать больше кода для сравнения.

0 голосов
/ 24 апреля 2019

Зачем вам два списка понимания, когда вы можете сделать это за одну итерацию.Я также отсортирую список заранее, чтобы позаботиться о зашифрованных списках, таких как ['data1', 'data3', 'data2-m', 'data1', 'data1-m', 'data3-m']

files = ['data1', 'data2', 'data3', 'data1-m', 'data2-m', 'data3-m']
noised_files = []
original_files = []

for file in sorted(files):
    if file.endswith('-m'):
        noised_files.append(file)
    else:
        original_files.append(file)
print(noised_files)
print(original_files)
#['data1-m', 'data2-m', 'data3-m']
#['data1', 'data2', 'data3']
...