Seite 1 von 1
Einfachste Möglichkeit, iterable[0] zu erhalten...
Verfasst: Sonntag 10. Juli 2011, 16:04
von mutetella
Hallo,
welches ist wohl die einfachste Möglichkeit, das erste Element eines iterierbaren Objektes zu erhalten?
mutetella
Re: Einfachste Möglichkeit, iterable[0] zu erhalten...
Verfasst: Sonntag 10. Juli 2011, 16:06
von sma
Ich würde es so machen:
Stefan
Re: Einfachste Möglichkeit, iterable[0] zu erhalten...
Verfasst: Sonntag 10. Juli 2011, 16:07
von lunar
Re: Einfachste Möglichkeit, iterable[0] zu erhalten...
Verfasst: Sonntag 10. Juli 2011, 16:44
von mutetella
@sma
Ja klar... :_KlatschtSichAnDieStirnSmiley_:
next() ist super, danke!
@lunar
'sentinel' bringt mir an der Stelle aber nichts, ich möchte ja ohne jedwede Prüfung einfach nur das 1. Element eines Iterators...
Oder verstehe ich das falsch?
Mir ist gerade noch
eingefallen, ist aber etwas 'umwegiger' als die 'next'-Lösung.
mutetella
Re: Einfachste Möglichkeit, iterable[0] zu erhalten...
Verfasst: Sonntag 10. Juli 2011, 16:47
von cofi
mutetella hat geschrieben:@lunar
'sentinel' bringt mir an der Stelle aber nichts, ich möchte ja ohne jedwede Prüfung einfach nur das 1. Element eines Iterators...
Oder verstehe ich das falsch?
Schau dir nochmal die Klammersetzung an. Das `None` gehoert zu `next`, nich `iter`.
Code: Alles auswählen
In [3]: next(iter([]))
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
/home/cofi/<ipython console> in <module>()
StopIteration:
In [4]: next(iter([]), None)
Re: Einfachste Möglichkeit, iterable[0] zu erhalten...
Verfasst: Sonntag 10. Juli 2011, 17:54
von jbs
@mutella: Probier deinen Ansatz mal mit itertools.count oder ähnlichem.
Re: Einfachste Möglichkeit, iterable[0] zu erhalten...
Verfasst: Sonntag 10. Juli 2011, 18:09
von mutetella
@cofi:
Ok, danke, war schlampig von mir...
@jbs:
Stimmt, da gäb's wohl ein Problem...
Die 'next'-Lösung ist gut. Ich bleib' dabei!
Das ganze benötige ich für eine list-Klasse, die immer nur aus 1 Element bestehen darf:
Code: Alles auswählen
class OneItemList(list):
def __init__(self, iterable=None):
if iterable is not None:
self.append(next(iter(iterable), None))
def append(self, item):
self[:] = iter((item,))
def extend(self, item):
self[:] = iter((item,))
Hab' ich etwas entscheidendes falsch gemacht?
mutetella
Re: Einfachste Möglichkeit, iterable[0] zu erhalten...
Verfasst: Sonntag 10. Juli 2011, 18:22
von lunar
@mutetella: Die Implementierung von ".extend()" stimmt nicht mit der erwarteten Semantik von ".extend()" überein, ".append()" lässt sich vereinfachen zu "self[:] = [item]".
Der Sinn einer einelementigen Liste erschließt sich mir allerdings nicht.
Re: Einfachste Möglichkeit, iterable[0] zu erhalten...
Verfasst: Sonntag 10. Juli 2011, 19:32
von mutetella
@lunar:
'extend' müsste demnach so aussehen:
Code: Alles auswählen
...
def extend(self, iterable):
self.append(next(iter(iterable), None))
Wobei mir schon auch klar ist, dass das kein 'extend' mehr ist, aber eine 'OneItemList' eben nur ein Element haben darf.
Der Sinn ist folgender:
Ich habe eine PatternFactory, die mir searchpatterns erstellt. Ein searchpattern besteht dabei aus einem Attributnamen und einer Liste von Suchbegriffen. Ist eine collection 'multiple', können mehrere Suchbegriffe verwendet werden. Andernfalls immer nur einer.
Der Einfachheit halber verwende ich für multiple-collections normale Listen, für nicht-multiple-collections meine OneItemList, die ich genauso verwenden kann, allerdings eben immer nur 1 Element enthält.
Der momentane Stand sieht wie folgt aus:
Code: Alles auswählen
import collections
class OneItemList(list):
def __init__(self, iterable=None):
if iterable is not None:
self.append(next(iter(iterable), None))
def append(self, item):
self[:] = [item]
def extend(self, iterable):
self.append(next(iter(iterable), None))
class PatternFactory(object):
def __init__(self):
self._stock = {}
def add_collection(self, name, multiple=True, operators=True):
if multiple:
list_ = list
else:
list_ = OneItemList
self._stock[name] = {}
if operators:
self._stock[name]['pattern'] = collections.defaultdict(list_)
else:
self._stock[name]['pattern'] = list_()
self._stock[name]['operators'] = operators
def switch(self, name, value, operator_=None):
operator_ = operator_ or 'and_'
if self._stock[name]['operators']:
pattern = self._stock[name]['pattern'][operator_]
else:
pattern = self._stock[name]['pattern']
if value in pattern:
pattern.remove(value)
else:
pattern.append(value)
def _pattern(self):
pattern = {}
for name, value in self._stock.iteritems():
if self._stock[name]['operators']:
values = self._stock[name]['pattern'].values()
else:
values = self._stock[name]['pattern']
if any(values):
pattern[name] = value['pattern']
return pattern
pattern = property(_pattern)
Code: Alles auswählen
In [40]: p = pattern.PatternFactory()
In [41]: p.add_collection('OnlyOneNumber', multiple=False, operators=False)
In [42]: p.switch('OnlyOneNumber', 1)
In [43]: p.pattern
Out[43]: {'OnlyOneNumber': [1]}
In [44]: p.switch('OnlyOneNumber', 2)
In [45]: p.pattern
Out[45]: {'OnlyOneNumber': [2]}
In [46]: p.switch('OnlyOneNumber', 2)
In [47]: p.pattern
Out[47]: {}
mutetella