Ich habe zwei Python-Listen, eine ist eine Liste von Schlüsselwörtern und die andere ist eine Liste von Dateinamen. Ich muss die Liste der Dateinamen basierend auf den Schlüsselwörtern analysieren, die ich habe. Ich möchte, dass Python den Dateinamen mit einem Schlüsselwort vergleicht und dann eine Operation ausführt, die darauf basiert, mit welchem Schlüsselwort es abgeglichen wird.

Was ich habe, sieht so aus:

keywords = ["_CMD_","_COMM_","_RETRANSMIT_"]
file_list = ['2B_CMD_2015.txt','2C_CMD_2015.txt','RETRANSMIT_2015.txt']

for f_name in file_list:
  for keyword in keywords:
    if keyword in f_name:
      #perform operation based on what keyword is matched
    else:
      #print an error

Das Problem, das ich damit habe, ist, dass es, da es die Schlüsselwörter durchläuft, einen Fehler druckt, bis es das Schlüsselwort im Dateinamen findet und dann die Operation ausführt, aber Ich möchte nur, dass es einen Fehler druckt, wenn Keines der Schlüsselwörter wird in dem Dateinamen gefunden, nach dem gesucht wird .

Ich habe versucht, any() zu verwenden, aber das scheint die Überprüfung von Dateien zu beenden, nachdem eine Übereinstimmung gefunden wurde. Zum Beispiel mit

for keyword in keywords:
  if any(keyword in f_name for f_name in file_list):
    print f_name
    print keyword

Kehrt zurück

2B_CMD_2015.txt
_CMD_
2B_CMD_2015.txt
_RETRANSMIT_

Welches ist nicht richtig.

Bearbeiten Ich habe auch versucht, Regex zu verwenden, bin mir aber nicht sicher, ob ich es richtig mache:

for keyword in keywords:
  for item in wordlist:
    if re.search(keyword,item) is not None:
        print keyword
        print item
    else:
        print "nope"

Kehrt zurück:

nope
nope
nope
_CMD_
2B_CMD_2015.txt
_CMD_
2C_CMD_2015.txt
nope
nope
nope
_RETRANSMIT_
_RETRANSMIT_2015.txt
nope
nope
nope

Kann mir jemand dabei helfen? Ich denke, es sollte nicht so schwierig sein.

4
kdubs 6 Aug. 2015 im 21:32

5 Antworten

Beste Antwort

Erwägen Sie die Verwendung von { {X0}} anstelle von if-else:

for f_name in file_list:
  for keyword in keywords:
    if keyword in f_name:
      print "Found keyword %s in name %s"%(keyword, f_name)
      break
  else:
    print "Found no keyword"

Beachten Sie die Einrückungsstufe. Der Block else entspricht dem for und nicht dem if. Beachten Sie auch, dass if mit break enden muss, wenn Sie die Ausführung von for-else vermeiden möchten.

3
Robᵩ 6 Aug. 2015 im 19:35

Der grundlegende Weg, dies zu tun, besteht darin, ein Flag zu setzen:

for f_name in file_list:
    flag = False
    for keyword in keywords:
        if keyword in f_name:
            flag = True
            #perform operation based on what keyword is matched
    if not flag:
        #print an error
1
TigerhawkT3 6 Aug. 2015 im 18:37

Filtern Sie die Liste mit any und verwenden Sie sie dann:

keywords = ["_CMD_","_COMM_","_RETRANSMIT_"]
file_list = ['2B_CMD_2015.txt','2C_CMD_2015.txt','RETRANSMIT_2015.txt']
filtered = [file_name for file_name in file_list if any(keyword in file_name for keyword in keywords)]
if filtered:
    # do stuff with 'filtered'
    print("processing files...")
else:
    print("error")

Beispiel:

>>> keywords = ["_CMD_","_COMM_","_RETRANSMIT_"]
>>> file_list = ['2B_CMD_2015.txt','2C_CMD_2015.txt','RETRANSMIT_2015.txt']
>>> filtered = [file_name for file_name in file_list if any(keyword in file_name for keyword in keywords)
...
... ]
>>> filtered
['2B_CMD_2015.txt', '2C_CMD_2015.txt']
0
Reut Sharabani 6 Aug. 2015 im 18:36

Ich schlage vor, keywords eine Liste von Tupeln zu erstellen, die jedes Schlüsselwort mit dem Handler koppelt. Sie können das Konstrukt for..else verwenden, um Dateien zu verarbeiten, die nicht übereinstimmen. Betrachten Sie z.

def handleCmd(fn):
    print "handleCmd: " + fn

def handleComm(fn):
    print "handleComm: " + fn

def handleRetransmit(fn):
    print "handleRetransmit: " + fn

keywords = [ ( "_CMD_", handleCmd ),
             ( "_COMM_", handleComm ),
             ( "RETRANSMIT_", handleRetransmit ),
           ]


file_list = ['2B_CMD_2015.txt','2C_CMD_2015.txt','RETRANSMIT_2015.txt','bogus.t>

for fn in file_list:
    for kw, handle in keywords:
        if kw in fn:
            handle(fn)
            break
    else:
        print "OH NOE"

Dies wird gedruckt

handleCmd: 2B_CMD_2015.txt
handleCmd: 2C_CMD_2015.txt
handleRetransmit: RETRANSMIT_2015.txt
OH NOE
0
Frerich Raabe 6 Aug. 2015 im 18:38

for-else kann Ihnen helfen. Die else -Klausel wird ausgeführt, wenn die innere for -Schleife nicht unterbrochen wird. Dies geschieht nur, wenn Sie eine Übereinstimmung finden. Beachten Sie, dass dies bedeutet, dass nur die erste Übereinstimmung berücksichtigt wird und nicht nach weiteren Übereinstimmungen gesucht wird.

keywords = ["_CMD_","_COMM_","_RETRANSMIT_"]
file_list = ['2B_CMD_2015.txt','2C_CMD_2015.txt','RETRANSMIT_2015.txt']

for f_name in file_list:
  for keyword in keywords:
    if keyword in f_name:
      #perform operation based on what keyword is matched
      break
  else:
    #print an error
1
iobender 6 Aug. 2015 im 18:36