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?

Code: Alles auswählen

for element in iterable:
    return element
mutetella

Re: Einfachste Möglichkeit, iterable[0] zu erhalten...

Verfasst: Sonntag 10. Juli 2011, 16:06
von sma
Ich würde es so machen:

Code: Alles auswählen

element = next(iter(iterable))
Stefan

Re: Einfachste Möglichkeit, iterable[0] zu erhalten...

Verfasst: Sonntag 10. Juli 2011, 16:07
von lunar

Code: Alles auswählen

next(iter(iterable), None)

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

Code: Alles auswählen

list(iterable)[0]
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... :oops:

@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