如何通过检查python列表是否匹配给定模式来对其进行排序?

时间:2019-02-06 09:07:07

标签: python python-3.x list sorting dictionary

对不起,我的英语。

我正在用python编写一个tkinter程序,但是我一直坚持对列表进行排序。让我解释一下。

我想构建一个函数,该函数将一个(用户输入)字符串列表作为参数,并根据它们的元素是否与某个字典键匹配来以不同的顺序返回相同的列表。

我已将与每个键相关联的顺序放在dict中。

dic=dict(organiza=1,autor=1,direct=1,docen=1,exp=1,dirig=1,ponen=1,fecha=2,día=2,dia=2,cuándo=2,cuando=2,lugar=3,sitio=3,locali=3,situa=3,direcci=3,ubica=3,web=4,link=4,enlace=4,página=4,pagina=4)

我想要的是,如果我选择了一个列表:

    lis=['TITLE:BLAH,BLAH..', 'web: www.something.es', 'situación: UCM University', 'Director: Someone', 'Fecha: some date']

输出应为:

    ['TITLE:BLAH,BLAH..','Director: Someone', 'Fecha: some date', 'situación: UCM University' 'web: www.something.es']

即我要的顺序是“ TITLE(这是有史以来第一个,没有变化),Director,Fecha,Situación,Web”或其含义变体。

因为程序必须检查列表并与dict键进行比较,然后按dict值对其进行排序。 如您所见,没有必要将每个单词字符串作为一个整体进行匹配,如果单词的某些部分在“:”之前与某个键匹配,则必须将其考虑在内。

    texto=self.master.clipboard_get() #obtenemos un string del clipboard
    texto=texto.split('\n') #separamos cada parrafo en una entrada de una lista
    texto=list(map(str.strip,texto)) #eliminamos posibles espacios iniciales y finales en cada entrada
    N=len(texto) #medimos su longitud
    x=[] #inicializamos la lista de items no deseados
    for i in range(N): #recorremos cada elemento de la lista
        n=len(texto[i]) #longitud del elemento en cuestion
        check=texto[i]==' '*n #si el elemento es solo espacio en blanco
        if check==True:
            x.append(texto[i]) #añadimos el item no deseado
    texto = [e for e in texto if e not in x] #con esto ya tenemos la lista con las entradas a poner en los campos
    N=len(texto) #volvemos a medir su longitud
    if N>5:
        return messagebox.showerror("Atención", "El texto que desea pegar tiene más de 5 líneas. El número de campos debe ser compatible con las celdas que se desea rellenar.")
    elif N<5: #si es menor que 5 completamos campos con entradas vacias
        while len(texto)<5:
            texto.append('')
    dic=dict(organiza=1,autor=1,direct=1,docen=1,exp=1,dirig=1,ponen=1,fecha=2,día=2,dia=2,cuándo=2,cuando=2,lugar=3,sitio=3,locali=3,situa=3,direcci=3,ubica=3,web=4,link=4,enlace=4,página=4,pagina=4)#diccionario con el orden de las claves
    new_order=[i for i in range(5)] #lista que llevara los nuevos ordenes de texto
    iteracion=itertools.product(range(1,N), dic.keys())
    for i, j in iteracion: #un loop es sobre el vector texto y otro sobre las claves del diccionario
        if texto[i].lower().find(j,0,texto[i].find(':'))!=-1: #si en alguna entrada del vector texto encuentra alguna clave j antes de los :
            new_order[i]=dic[j] #en el vector de nuevas posiciones asignamos la que nos dice el diccionario
    texto=[x for _,x in sorted(zip(new_order,texto))]
    self.var_entry_titulo.set(texto[0])
    self.var_entry_director.set(texto[1][texto[1].find(':')+1:].strip())
    self.var_entry_fecha.set(texto[2][texto[2].find(':')+1:].strip())
    self.var_entry_lugar.set(texto[3][texto[3].find(':')+1:].strip())
    self.var_entry_web.set(texto[4][texto[4].find(':')+1:].strip())
    print(texto,new_order)

上面的代码根本不起作用。我已经尝试了很多,但都失败了。

谢谢大家,希望您能理解我要解释的内容,但我知道这是一个很糟糕的论点

4 个答案:

答案 0 :(得分:1)

问题中的词典缺少“ title”的关键字,该关键字的值应为零,因为它排在第一位。另外,在调用key过程时应使用sorted参数,这样可以大大简化问题。这是我的建议:

import re

# this is the preferred syntax for creating a dictionary
dic = {'title':0,'organiza':1,'autor':1,'direct':1,'docen':1,'exp':1,'dirig':1,'ponen':1,'fecha':2,'día':2,'dia':2,'cuándo':2,'cuando':2,'lugar':3,'sitio':3,'locali':3,'situa':3,'direcci':3,'ubica':3,'web':4,'link':4,'enlace':4,'página':4,'pagina':4}

def rank(ele):
    # split each element in words
    ele = ele.lower()
    words = re.split(r'[: ]+', ele)
    # check each word to see if it's a
    # substring of one of the dictionary keys
    for w in words:
        for word, value in dic.items():
            if word in w:
                # return first match
                return value
    # if no match is found, send word to the end
    return float('+inf')

它按预期工作:

lis = ['TITLE:BLAH,BLAH..', 'web: www.something.es', 'situación: UCM University', 'Director: Someone', 'Fecha: some date']
sorted(lis, key=rank)
=> ['TITLE:BLAH,BLAH..', 'Director: Someone', 'Fecha: some date', 'situación: UCM University', 'web: www.something.es']

答案 1 :(得分:1)

在这里您可以尝试:

dic=dict(organiza=1,autor=1,direct=1,docen=1,exp=1,dirig=1,ponen=1,fecha=2,día=2,dia=2,cuándo=2,cuando=2,lugar=3,sitio=3,locali=3,situa=3,direcci=3,ubica=3,web=4,link=4,enlace=4,página=4,pagina=4)
lis = ['TITLE:BLAH,BLAH..', 'web: www.something.es', 'situación: UCM University', 'Director: Someone',
   'Fecha: some date']
li = [[] for i in range(len(lis))]
li[0].append(lis[0])
for x in lis:
    for j in dic.keys():
        if j in x.split(':')[0].lower():
            li[dic[j]].append(x)

print(sum(li,[]))
# ['TITLE:BLAH,BLAH..', 'Director: Someone', 'Fecha: some date', 'situación: UCM University', 'web: www.something.es']

答案 2 :(得分:0)

您需要创建一个排序键,以便按“:”后的值进行排序。 “ sort_key”函数返回“:”之后的字符串,这将是排序的参数。

lis=['TITLE: BLAH,BLAH..', 'web: www.something.es', 'situación: UCM University', 'Director: Someone', 'Fecha: some date']
def sort_key(elem):
    return elem.split(': ')[1]
print(sorted(lis,key=sort_key))

答案 3 :(得分:0)

dic = {'title':0,'organiza':1,'autor':1,'direct':1,'docen':1,'exp':1,'dirig':1,'ponen':1,'fecha':2,'día':2,'dia':2,'cuándo':2,'cuando':2,'lugar':3,'sitio':3,'locali':3,'situa':3,'direcci':3,'ubica':3,'web':4,'link':4,'enlace':4,'página':4,'pagina':4}

lis = ['TITLE:BLAH,BLAH..', 'web: www.something.es', 'situación: UCM University', 'Director: Someone', 'Fecha: some date']

def get_ordered_add(value):
    keys = dic.keys()
    title = value.split(":")[0].lower()
    return  [dic[kys]
                 for kys in keys 
                 if title.startswith(kys)][0]

sorted(lis, key=get_ordered_add)
>>>['TITLE:BLAH,BLAH..',
    'Director: Someone',
    'Fecha: some date',
    'situaci\xc3\xb3n: UCM University',
    'web: www.something.es']
相关问题