سؤال

أنا خلقت وظيفة الأداة العودة المتوقعة بند واحد من مولد التعبير

print one(name for name in ('bob','fred') if name=='bob')

هذا هو وسيلة جيدة للذهاب عن ذلك ؟

def one(g):
    try:
        val = g.next()
        try:
            g.next()
        except StopIteration:
            return val
        else:
            raise Exception('Too many values')
    except StopIteration:
        raise Exception('No values')
هل كانت مفيدة؟

المحلول

والحل الأبسط هو استخدام الصفوف (tuple) التفريغ. وهذا يحدث بالفعل كل ما تريد، بما في ذلك التحقق أنه يحتوي على عنصر واحد بالضبط.

وبند واحد:

 >>> name, = (name for name in ('bob','fred') if name=='bob')
 >>> name
 'bob'

وعناصر كثيرة جدا:

>>> name, = (name for name in ('bob','bob') if name=='bob')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack

وليس هناك أي عناصر:

>>> name, = (name for name in ('fred','joe') if name=='bob')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: need more than 0 values to unpack

نصائح أخرى

ونهج بسيط:

print (name for name in ('bob', 'fred') if name == 'bob').next()

إذا كنت تريد حقا خطأ عند وجود أكثر من قيمة واحدة، ثم كنت في حاجة الى وظيفة. أبسط أستطيع أن أفكر في غير (على تحرير لتعمل مع القوائم أيضا):

def one(iterable):
    it = iter(iterable)
    val = it.next()
    try:
        it.next()
    except StopIteration:
        return val
    else:
        raise Exception('More than one value')

لأولئك الذين يستخدمون أو المهتمين في طرف ثالث المكتبة ، more_itertools تنفذ هذه الأداة مع الأم معالجة الأخطاء:

> pip install more_itertools

رمز

import more_itertools as mit


mit.one(name for name in ("bob", "fred") if name == "bob")
# 'bob'

mit.one(name for name in ("bob", "fred", "bob") if name == "bob")
# ValueError: ...

mit.one(name for name in () if name == "bob")
# ValueError: ...

انظر more_itertools مستندات للحصول على التفاصيل.على كود المصدر الأساسي يشبه الجواب المقبول.

هل لديك نظرة على itertools.islice () طريقة .

>>> i2=itertools.islice((name for name in ('bob','fred') if name=='bob'),0,1,1)
>>> i2.next()
'bob'
>>> i2.next()
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
StopIteration
>>> 
<اقتباس فقرة>   

وهذه الوحدة تنفذ عددا من اللبنات مكرر مستوحاة من يبني من لغات البرمجة هاسكل وSML. تم إعادة صياغة كل في شكل مناسب لبيثون.

     

وحدة توحد مجموعة أساسية من أدوات سريعة، ذاكرة كفاءة التي هي مفيدة في حد ذاتها أو في تركيبة. توحيد يساعد على تجنب القراءة والموثوقية المشاكل التي تنشأ عندما خلق العديد من مختلف الأفراد الخاصة تطبيقات مختلفة قليلا، ولكل منها المراوغات الخاصة واصطلاحات التسمية.

     

تم تصميم أدوات لدمج بسهولة مع بعضها البعض. وهذا يجعل من السهل لبناء المزيد من الأدوات المتخصصة بإيجاز وكفاءة في بيثون النقي.

هل تقصد؟

def one( someGenerator ):
    if len(list(someGenerator)) != 1: raise Exception( "Not a Singleton" )

وماذا تحاول تحقيقه مع كافة التعليمات البرمجية اضافية؟

وهنا هو بلدي محاولة في وظيفة one(). وأود أن تجنب الدعوة .next() صريحة واستخدام لحلقة بدلا من ذلك.

def one(seq):
    counter = 0
    for elem in seq:
        result = elem
        counter += 1
        if counter > 1:
            break
    if counter == 0:
        raise Exception('No values')
    elif counter > 1:
        raise Exception('Too many values')
    return result

أولا، (للإجابة على السؤال الفعلي!) والحل تعمل بشكل جيد كما ان المتغيرات الأخرى المقترحة.

وأود أن أضيف أنه في هذه الحالة، IMO والمولدات هي مفرطة في التعقيد. إذا كنت تتوقع أن يكون قيمة واحدة، فسوف يكون من المحتمل أبدا أن يكون بما فيه الكفاية لاستخدام الذاكرة لتكون مصدر قلق، لذلك كنت قد استخدمت فقط ما هو واضح وأكثر وضوحا:

children = [name for name in ('bob','fred') if name=='bob']
if len(children) == 0:
    raise Exception('No values')
elif len(children) > 1:
    raise Exception('Too many values')
else:
    child = children[0]

وماذا عن استخدام لبيثون ل.. في جملة مع عداد؟ على غرار الجواب دون علم و.

def one(items):
    count = 0
    value = None

    for item in items:
        if count:
            raise Exception('Too many values')

        count += 1
        value = item

    if not count:
        raise Exception('No values')

    return value
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top