for schleife in eine Liste

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
redone
User
Beiträge: 4
Registriert: Dienstag 20. Februar 2018, 14:04

Hallo liebes Forum,

ich bin gerade dabei Python zu erlernen steh jedoch gerade vor einem Problem was ich nicht gelöst bekomme und im internet auch nicht wirklich fündig werde.
Es geht um das Thema Listen

hier mal mein code:

Code: Alles auswählen

import subprocess
aufruf = subprocess.Popen(["ifconfig"], stdout=subprocess.PIPE)
list = []

for line in aufruf.stdout:                                                           
    line = str(line.strip())                                                     
    line = line.split(" ")
    list.append(line)
   
print(list)                                  
ich möchte die ausgabe in einer liste haben.
Jetzt bekomme ich für jede gelesene Zeile eine neue liste.
könnt ihr mir sagen nach was ich suchen muss oder mir auf die Sprünge helfen.

gruß redone
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@redone: wenn Du Dein Programm Zeile für Zeile durchgehst, dann erkennst Du, dass 'line.split()' an der vorkommenden Stelle vermutlich nicht das macht, was Du willst. Hast Du den Code einfach nur kopiert ('list' ist übrigens ein ganz schlechter Name) und suchst nun den Grund für das nicht gewünschte Verhalten?

Kürzer geht es wie folgt (Python 3.6):

Code: Alles auswählen

import subprocess
result = subprocess.run(["ifconfig"], stdout=subprocess.PIPE, encoding='utf8')
print([line for line in result.stdout.split('\n')])
Damit erhältst Du eine Liste mit allen Zeilen, so wie sie auch im Terminal ausgegeben würden.
redone
User
Beiträge: 4
Registriert: Dienstag 20. Februar 2018, 14:04

naja kopiert, rumprobiert, verändert so ziemlich alles

also line.strip() holt ja wenn ich es richtig verstanden habe die new lines raus?

line.split(" ") macht ja aus jeder zeile eine liste aufgrund der for schleife

ich möchte jetzt also aber nicht jede zeile in eine seperate liste in der liste sondern alle wörter in eine Liste.

so das ich die liste durchsuchen kann nach werten und diese wieder rum rausziehen kann in eine andere liste.

Konkret möchte ich eigentlich aus ifconfig die ipadresse in eine liste schieben.

Ich habs auch schon probiert zuerst die datei in eine text datei zu schreiben und sie von da wieder rauszuholen aber ich denke das war der falsche ansatz.

Zu deinem Code der funktioniert bei mir nicht der sagt das was mit encoding nicht stimmt wobei bei mir läuft python 3.5 und laut apt-get gibts keine neue version für mich ich probier aber auch auf einem Raspi rum mit Raspbian Stretch

danke schonmal und Grüße redone
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Der Aufruf von `str` ist nicht passend. Du willst ja eine Liste von Wörtern haben (und nicht einen String, der aussieht wie eine Liste), und die willst die Liste an die vorhande Liste anhängen. Oder genauer gesagt, du willst die vorhandene Liste um die neue Liste erweitern. Dafür gibt es die `extend`-Methode. Ungetestet müsste die Schleife dann so aussehen:

Code: Alles auswählen

for line in aufruf.stdout:                                                           
    line = line.strip()                                                  
    line = line.split(" ")
    list.extend(line)
Und wie kbr schon schrieb: Nenne deine Liste anders, z.B. `words`. Dann könnte man die Schleife so schreiben (ungetestet, mit zusätzlichen Vereinfachungen):

Code: Alles auswählen

for line in aufruf.stdout:                                                           
    words.extend(line.strip().split(" "))
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das strip() ist ebenfalls unnötig, denn split() kürzt die Zeilenenden bereits weg. Das wird letztlich also hierzu:

Code: Alles auswählen

words = [word for line in result.stdout for word in line.split()]
Möglicherweise will man auch lieber ein set() benutzen, um Duplikate zu vermeiden...
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@bords0: 'str' ist schon erforderlich, sofern keine Bytestrings verwendet werden sollen. Die optionale Angabe eines Encodings für 'subprocess.run' (seit Python 3.6) vereinfacht die Konvertierung.

@snafu: 'result.stdout' liefert bereits einen String zurück. Dadurch wird das Aufteilen in Wörter sogar noch einfacher:

Code: Alles auswählen

words = [word for word in result.stdout.split()]
Die Aufspaltung in Worte halte ich aber nicht für wirklich zielführend, um die von 'ifconfig' gelieferten Daten auszuwerten.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@kbr: das Encoding sollte wohl dem aktuellen Locale entsprechen. Die LC bei Dir dann komplett überflüssig:

Code: Alles auswählen

words = result.stdout.split()
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Sirius3: ohne Angabe eines Encodings öffnet subprocess.run die Rückgabe im Binär-Modus. Bei Angabe eines Encodings muss dieses natürlich passend gewählt sein. Wenn dieses nicht bekannt ist, wäre das aktuelle Local eine sinnvolle Annahme.
Wieso ich für die 'words' eine LC genommen habe, ist mir im Nachhinein völlig unklar.
redone
User
Beiträge: 4
Registriert: Dienstag 20. Februar 2018, 14:04

ich hab es geschafft also zumindest passiert jetzt das was ich wollte.
Die for schleife in Eckigen klammern hab ich nicht verstanden und auch nix gefunden um nach zu lesen was das ist.
Mittlerweile bin ich auch darin schlauer und letzten endes hat es mir auch die liste erstellt wie gewünscht.

der name liste und liste2 ist einfach für mich zum besseren verständnis hinter diesem script steckt kein wirklicher sinn ich wollte lediglich erlernen wie ich aus dem stdout die daten in eine liste bekomme um mir dann relevante Daten raus zuholen

Jetzt versteh ich nur eins noch nicht wenn ich start.count ('inet') eingebe kommt eine 2 zurück

bei start.index('inet') kommt eine 4 was dem richtigen wert entspricht?

Code: Alles auswählen

import subprocess

abfrage = subprocess.check_output("ifconfig").decode('utf8').split()         
liste2 = []

start = [liste for liste in abfrage]                                         
search = start.index('inet')
liste2.append(start[search +1])                                              
print(liste2)                                                                   


vielen dank für eure Hilfe

grüße redone
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@redone: warum machst Du auf so umtändliche Weise eine Kopie von ›abfrage‹, wobei ›start‹ nicht gerade ein besserer Name ist und die Kopie gar nicht gebraucht wird. Würde ›count‹ 4 als Ergebnis liefern, wäre das falsch. Vielleicht solltest Du mal nachlesen, was die Methoden wirklich machen.
redone
User
Beiträge: 4
Registriert: Dienstag 20. Februar 2018, 14:04

da hab ich wohl schneller getippt als überlegt zum Thema count.

na in der liste start hab ich ja alle wörter einzeln drin als String

dann geh ich mit index meinen wert suchen und schreib ihn mir dann in die eigentliche liste

gruß redone
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@redone: na, die Wörter stehen auch schon in abfrage einzeln als String drin.

Hier das ganze nochmal ohne diese leidigen Indexe:

Code: Alles auswählen

from itertools import dropwhile, islice
import subprocess

abfrage = subprocess.check_output("ifconfig").decode('utf8').split()         

liste2 = list(islice(dropwhile("inet".__ne__, abfrage),1,2))
print(liste2)
Antworten