如何按第三字符串的一部分对字符串列表进行排序?

时间:2019-03-29 09:17:09

标签: python python-3.x list sorting

初学者在这里:

我正在尝试对同一行中相应国家/地区的昵称列表进行排序。 它们以这种格式出现:

FODORGBR + HU-Szombathely-2

ZSOLDPTE + HU-Debrecen-3

THAUSKTR + DE-Herzogenaurach-1

WRIGHNIL + UK-SuttonColdfield-2

KUROTADR + SK-KysuckeNoveMesto-1

KLERNMTT + DE-Herzogenaurach-1

BIRKNJHA + DE-Erlangen-111

CANECVAD + SK-KysuckeNoveMesto-1

MALDESND + DE-Herzogenaurach-1

我想按带标题的国家缩写(例如HU,DE等)进行排序。 像这样:

DE:

THAUSKTR

KLERNMTT

BIRKNJHA

MALDESND


HU:

FODORGBR 

ZSOLDPTE

这是我想出的用来定义国家/地区的信息,但我不知道如何对所有国家/地区进行排序。

fw = open("NameList.txt")
for line_fw in fw:
    if not line_fw.strip():
        continue
    cross = line_fw.find("+")
    country = line_fw[cross+2:cross+4]

4 个答案:

答案 0 :(得分:0)

首先在" "上拆分列表,然后使用operator.itemgetter遍历列表的最后一个元素。

如果国家/地区代码始终是列表中的第3个元素,则将-1中的itemgetter替换为3

from operator import itemgetter

x = ["FODORGBR + HU-Szombathely-2","ZSOLDPTE + HU-Debrecen-3","THAUSKTR + DE-Herzogenaurach-1",
"WRIGHNIL + UK-SuttonColdfield-2","KUROTADR + SK-KysuckeNoveMesto-1","KLERNMTT + DE-Herzogenaurach-1",
"BIRKNJHA + DE-Erlangen-111","CANECVAD + SK-KysuckeNoveMesto-1","MALDESND + DE-Herzogenaurach-1"]

new_list = [i.split() for i in x]
new_list.sort(key=itemgetter(-1))

print([" ".join(i) for i in new_list])

输出:

['BIRKNJHA + DE-Erlangen-111', 'THAUSKTR + DE-Herzogenaurach-1', 'KLERNMTT + DE-Herzogenaurach-1', 'MALDESND + DE-Herzogenaurach-1', '
ZSOLDPTE + HU-Debrecen-3', 'FODORGBR + HU-Szombathely-2', 'KUROTADR + SK-KysuckeNoveMesto-1', 'CANECVAD + SK-KysuckeNoveMesto-1', 'WRI
GHNIL + UK-SuttonColdfield-2']

答案 1 :(得分:0)

使用re.searchcollections.defaultdict

import re
from collections import defaultdict

d = defaultdict(list)
with open('NameList.txt') as fw:
    for line in fw:
        code = re.search(' (\w{2})-', line).group(1)
        nick = re.search('(\w{8}) +', line).group(1)
        d[code].append(nick)

输出:

defaultdict(list,
            {'DE': ['THAUSKTR', 'KLERNMTT', 'BIRKNJHA', 'MALDESND'],
             'HU': ['FODORGBR', 'ZSOLDPTE'],
             'SK': ['KUROTADR', 'CANECVAD'],
             'UK': ['WRIGHNIL']})

答案 2 :(得分:0)

您用于查找国家/地区名称的代码就很好。处理文件时的一个建议:使用with- statement代替openclose。使用open时,如果在调用close之前的某个时间发生错误,则可能是文件未正确关闭,这可能会弄乱所有事情。无论在相应的代码块内发生什么,with都会关闭文件(其工作原理类似于try - finally,有关更多信息,请参见上面的链接)。因此,像这样:

with open('NameList.txt', 'r') as fw:
    for line_fw in fw:
        ...

确保该文件将始终关闭。顺便说一句,您可以只使用line.find('+'),而不使用line.split('+'),它会占用整个字符串切片部分。

现在,您的问题是:这里有几种使用的可能性。最简单的方法是为每个国家/地区定义一个列表,然后将相应的名称附加到正确的列表中:

de = []
hu = []
uk = []
sk = []

with open('NameList.txt', 'r') as fw:
    for line_fw in fw:
        if not line_fw.strip():
            continue
        country = line_fw.split('+')[1].split('-')[0].strip()
        nickname = line_fw.split('+')[0]
        if country == 'DE':
            de.append(nickname)
        elif country == 'HU':
            hu.append(nickname)
        elif country == 'UK':
            uk.append(nickname)
        else:
            sk.append(nickname)

这将为每个国家/地区返回一个列表,其中包含相应的昵称。如您所见,这非常笨拙且冗长。更为优雅的解决方案是使用dictionary,将国家/地区作为键,并将名称列表作为值:

d = {}

with open('NameList.txt', 'r') as fw:
    for line_fw in fw:
        if not line_fw.strip():
            continue
        country = line_fw.split('+')[1].split('-')[0].strip()
        nickname = line_fw.split('+')[0].strip()
        try:
            d[country].append(nickname)  # if country already exists in d, append the nickname
        except KeyError:
            d[country] = [nickname]  # if country doesn't exist in d, make a new entry

这将创建一个像这样的字典(我只是用前几行来说明它):

{'HU': ['FODORGBR', 'ZSOLDPTE'], 'DE': ['THAUSKTR'], 'UK': ['WRIGHNIL']}

现在,有更多用于提取国家和昵称的优雅解决方案,但是其中一些已在其他答案中指出。

最后,如果我做对了,您想将结果写入新文件,或者至少将它们打印出来。假设您有上述形式的字典。只需通过for k in d:遍历其键,在其间添加一些换行符('\n'),然后使用join将列表转换为一个字符串,并在所有项目之间添加换行符:

for k in d:
    print(k + ':\n' + '\n'.join(d[k]) + '\n')

将打印:

HU:
FODORGBR 
ZSOLDPTE 

DE:
THAUSKTR 

UK:
WRIGHNIL 

通过添加with open(outputfile, 'w') as f:并将print替换为f.write,您可以轻松地将其写入新文件。

答案 3 :(得分:0)

以下是可帮助您的代码段:

sample = '''
FODORGBR + HU-Szombathely-2

ZSOLDPTE + HU-Debrecen-3

THAUSKTR + DE-Herzogenaurach-1

WRIGHNIL + UK-SuttonColdfield-2

KUROTADR + SK-KysuckeNoveMesto-1

KLERNMTT + DE-Herzogenaurach-1

BIRKNJHA + DE-Erlangen-111

CANECVAD + SK-KysuckeNoveMesto-1

MALDESND + DE-Herzogenaurach-1
'''
def find_between( s, first, last ):
    try:
        start = s.index( first ) + len( first )
        end = s.index( last, start )
        return s[start:end]
    except ValueError:
        return ""

data = sample.splitlines()

elements = {}
for indv in data:
    code = find_between(indv,"+","-").strip()
    value = find_between(indv,"","+").strip()
    if code != '' and code in elements:
        values = []
        values.append(value)
        values.extend(elements[code])
        values = list(filter(None, values))
        values.sort()
        elements[code] = values
    elif code != '':
        values = []
        values.append(value)
        elements[code] = values

print(elements)

输出: {'HU':['FODORGBR','ZSOLDPTE'],'DE':['BIRKNJHA','KLERNMTT','MALDESND','THAUSKTR'],'UK':['WRIGHNIL'],'SK' :['CANECVAD','KUROTADR']}