Teiliste in Liste enthalten?

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
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Ich möchte gerne überprüfen, ob eine Liste mit einer anderen Liste übereinstimmt, die unter Umständen mehr Einträge hat:

Leider geht es so nicht :-(

Code: Alles auswählen

>>> l1 = ["1","2","3","4"]
>>> l2 = ["2","3"]
>>> l2 in l1
False
Die Idee es so zu machen bekam ich aus dem Wiki:
http://wiki.python.de/Neue_Features?hig ... essertesIn

cu Sebastian
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Mr_Snede hat geschrieben:Ich möchte gerne überprüfen, ob eine Liste mit einer anderen Liste übereinstimmt, die unter Umständen mehr Einträge hat:

Leider geht es so nicht :-(

Code: Alles auswählen

>>> l1 = ["1","2","3","4"]
>>> l2 = ["2","3"]
>>> l2 in l1
False
Die Idee es so zu machen bekam ich aus dem Wiki:
http://wiki.python.de/Neue_Features?hig ... essertesIn

cu Sebastian
Das würde bedeuten:

>>> l1 = ["1","2","3",["2","3"],"4"]
>>> l2 in l1
True

Du suchst ein Liste als Listenelement in l1.
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

och menno,
warum muss denn das was ich nicht will auch noch logisch bzw sinnvoll sein? :evil:

Dann werde ich halt die größere Liste manuell erst zusammenstutzen.
Und mir später mal meine Datenstruktur überdenken.

Cu sebastian
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

Mr_Snede hat geschrieben:och menno,
warum muss denn das was ich nicht will auch noch logisch bzw sinnvoll sein? :evil:

Dann werde ich halt die größere Liste manuell erst zusammenstutzen.
Und mir später mal meine Datenstruktur überdenken.

Cu sebastian
Ich finde das Problem interessant, weiss aber auch keine (einfache)
Lösung.

Intuitiv hätte ich das wahrscheinlich auch so probiert.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

etwa sowas?

Code: Alles auswählen

set(l2).issubset(set(l1))
TUFKAB – the user formerly known as blackbird
Francesco
User
Beiträge: 824
Registriert: Mittwoch 1. Dezember 2004, 12:35
Wohnort: Upper Austria

blackbird hat geschrieben:etwa sowas?

Code: Alles auswählen

set(l2).issubset(set(l1))
Super, danke!
Wieder was neues gelernt, werde ich mir gleich notieren.

Trotzdem:
Bei strings geht es ja auch:
t = "teststring"
tsub= "estsr"

bei der Liste muessten die Argumente irgendwie nicht als Liste
übergeben werden können, sondern als Elemente,
dann könnte man es theoretisch auch so behandeln. :?
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Danke schön.

nach ein wenig Doku[1] und Forum lesen sieht es bei mir nun so aus:

Code: Alles auswählen

Python 2.3.5 (#2, Nov 20 2005, 16:40:39)
[GCC 4.0.3 20051111 (prerelease) (Debian 4.0.2-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> l1 = ["1","2","3","4"]
>>> l2 = ["2","3"]
>>> l2 in l1
False
>>> import sets
>>> sets.Set(l2).issubset(sets.Set(l1))
True
cu Sebastian

[1] http://www.python.org/doc/2.3.5/lib/module-sets.html
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Du weisst, dass der Vergleich mit Strings nicht angebracht ist?

Denn:

Code: Alles auswählen

modelnine@phoenix ~ $ python
Python 2.4.2 (#1, Feb  5 2006, 17:30:13)
[GCC 4.0.2 (Gentoo 4.0.2-r3, pie-8.7.8)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> "hello" in "test hello 2"
True
>>> "hello" in "test heiko luft"
False
>>> set(["1","2"]).issubset(set(["1","2","3","4"]))
True
>>> set(["1","2"]).issubset(set(["2","3","1","4"]))
True
>>>
Wenn's Dir darum geht eine wirkliche "Unterliste" zu finden wie das str in str macht (und eben nicht nur zu gucken ob die Elemente aus der ersten Liste in der zweiten drin sind, unabhängig von der Ordnung), dann mußt Du's selbst implementieren.
--- Heiko.
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

In Worten lautet mein Problem:
Sind alle!! Elemente der kürzeren Liste in der Längeren enthalten?

So wie du es beschreibst und ich die Doku verstanden habe tun Sets genau das.

cu Sebastian
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Dein Problem mag es lösen, aber ich wollte darauf hinaus dass der Vergleich mit dem str in str nicht angebracht ist, weil der nicht prüft ob alle Elemente (also Zeichen) in dem anderen String vorhanden sind, sondern ob der Unterstrings s1 im String s2 vorhanden ist.

Ganz was anderes als zu Prüfen ob das eine eine Untermenge des anderen ist...

PS: Es war sogar nicht an Dich gerichtet, sondern an Franceso, der nämlich die str in str-Geschichten aufgebracht hat...
--- Heiko.
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

hmm irgendwo hapert es bei der Umsetzung von dem Beispiel für mein Programm.

Igendwie stehe ich mit der Fehlermeldung etwas sei nicht hashbar auf Kriegsfuß.

Gegeben ist (stark gekürzter Auszug):

Code: Alles auswählen

class  Konto:
      def  __init__(self):
         self.konto_liste = []

   def import_csv(self, Pfad_zum_neuen_csv):
      # eine neue csv Datei in konto_liste einlesen
      # vorhandene Eintraege werden uebergangen

      in_file=file(Pfad_zum_neuen_csv, 'r')
      reader=csv.reader(in_file,mydialect)

      #if not zeile[1:] in self.konto_liste:
      if not sets.Set(zeile[1:]).issubset(sets.Set(self.konto_liste)):
         elf.konto_liste.append(zeile)

Code: Alles auswählen

Traceback (most recent call last):
  File "konto-core-002.py", line 267, in ?
    k.test_import_csv()
  File "konto-core-002.py", line 230, in test_import_csv
    self.import_csv("test1.csv")
  File "konto-core-002.py", line 89, in import_csv
    if not sets.Set(zeile[1:]).issubset(sets.Set(self.konto_liste)):
  File "/usr/lib/python2.3/sets.py", line 429, in __init__
    self._update(iterable)
  File "/usr/lib/python2.3/sets.py", line 374, in _update
    data[element] = value
TypeError: list objects are unhashable
Kann es daran liegen, dass self.konto_liste zu diesem Zeitpunkt noch leer ist?
r2d2
User
Beiträge: 43
Registriert: Donnerstag 2. März 2006, 23:05
Wohnort: Bielefeld

warum iterierst du nicht einfach über die listen?

Code: Alles auswählen

mylist1 = ["1","2","3","4"]
mylist2 = ["2","3"]

for item in mylist2:
    if item in mylist1:
        print item," in mylist1"
    else:
        print item," nicht in mylist1"
r2d2
äh, nimm diese schlange von meinem hals.
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Danke dir für den Tipp,
ich werde jetzt erst einmal in meinen Programm etwas aufräumen und eine Nacht drüber schlafen.

cu Sebastian
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Hier das Ergebnis eines harten Wochenende - mann habe ich gekäpft, aber ganz alleine geschafft.
Ich bin richtig stolz auf mich :-)


Was sagt ihr dazu?
(Ich hoffe ihr findet den Quellcode zwischen den Konsoleausgaben.)

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# iteriere ueber 2 2dimensionale Liste

import pprint
pp = pprint.PrettyPrinter(indent=4)

'''
Problembeschreibung:
- ein Teilstück einer Zeile aus neue_liste  ist in einer Zeile von alte_liste enthalten:
-- False:
      Zeile wird an alte_liste angehängt
      und bekommt den Namen der Datei mit, aus der neue_liste importiert wurde.
-- True:
      in der übereinstimmenden Zeile wird der Name der Datei,
      aus der neue_liste importiert wurde, eingetragen

Die Dateinamen werden hier durch die Strings "d1" und "d2" simmuliert 
'''

alte_liste = [ ["01", "11",["d1"], "21_a"],
               ["02", "12",["d1"], "22_a"],
               ["03", "13",["d1"], "23_a"] ]

neue_liste = [ ["02", "12",[], "22_n"],
               ["03", "13",[], "23_n"],
               ["04", "14",[], "24_n"] ]


def schonenthalten(zeile_neue_liste, alte_liste):
   print "-->schonenthalten aufgerufen"
   print " ", zeile_neue_liste, "(neue)"
   print " ",alte_liste[0], "(alte)"

   for index, item2 in enumerate(alte_liste):
      print "index", index
      print "len(alte_liste)", len(alte_liste)
      if zeile_neue_liste[:1] == item2[:1]:
         print "schon enthalten"
         print " ", zeile_neue_liste, "(alte)"
         print " ", item2, "(neue)"
         return [True, index]
      else:
         print "nix gleich:"
         print " ", zeile_neue_liste, "(neue)"
         print " ", item2, "(alte)"
         #schonenthalten(zeile_alte_liste, neue_liste[1:])
   print "ende von alte_liste erreicht"
   return [False,]


temp_list = []

for i_neu, item_neu in enumerate(neue_liste):
   print "\n~~~~~~~~~~~~~~~~~~~~~~~~"
   print i_neu,".ter Durchlauf enumerate(neue_liste):"
   print "item_neu:\n ", item_neu, "\n"
   ergebnis = schonenthalten(item_neu, alte_liste)
   print "ergebnis ",ergebnis
   if ergebnis[0] == True:
      print "alte_liste, Spalte:", ergebnis[1]
      print "alte_liste:\n ", alte_liste[ergebnis[1]]
      alte_liste[ergebnis[1]][2].append("d2")
      print "alte_liste:\n ", alte_liste[ergebnis[1]]
   else:
      item_neu[2].append("d2")
      temp_list.append(item_neu)



print "\n-------------\n Ergebnis:\n-------------"

pp.pprint(alte_liste + temp_list)
Das Ergebnis sieht dann so aus:

Code: Alles auswählen

-------------
 Ergebnis:
-------------
[   ['01', '11', ['d1'], '21_a'],
    ['02', '12', ['d1', 'd2'], '22_a'],
    ['03', '13', ['d1', 'd2'], '23_a'],
    ['04', '14', ['d2'], '24_n']]
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

habe grade beim Entfernen der print statements gesehen, dass ich einen kompletten "else Zweig" nicht brauche.

So sieht mein Prototyp also im Moment aus:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import pprint
pp = pprint.PrettyPrinter(indent=4)

alte_liste = [ ["01", "11",["d1"], "21_a"],
               ["02", "12",["d1"], "22_a"],
               ["03", "13",["d1"], "23_a"] ]

neue_liste = [ ["02", "12",[], "22_n"],
               ["03", "13",[], "23_n"],
               ["04", "14",[], "24_n"] ]


def schonenthalten(zeile_neue_liste, alte_liste):
   for index, item2 in enumerate(alte_liste):
      if zeile_neue_liste[:1] == item2[:1]:
         return [True, index]
   return [False,]

temp_list = []
for i_neu, item_neu in enumerate(neue_liste):
   ergebnis = schonenthalten(item_neu, alte_liste)
   if ergebnis[0] == True:
      alte_liste[ergebnis[1]][2].append("d2")
   else:
      item_neu[2].append("d2")
      temp_list.append(item_neu)

print "\n-------------\n Ergebnis:\n-------------"
pp.pprint(alte_liste + temp_list)
Antworten