python - كيف أتحقق إذا كانت القائمة فارغة؟




list is-empty (20)

على سبيل المثال ، إذا تم تمرير ما يلي:

a = []

كيف يمكنني التحقق لمعرفة ما إذا كان فارغًا؟


أفضل طريقة للتحقق مما إذا كانت القائمة فارغة

على سبيل المثال ، إذا تم تمرير ما يلي:

a = []

كيف يمكنني التحقق لمعرفة ما إذا كان فارغًا؟

اجابة قصيرة:

ضع القائمة في سياق منطقي (على سبيل المثال ، مع عبارة if أو while ). سيختبر False إذا كان فارغًا ، True خلاف ذلك. فمثلا:

if not a:                           # do this!
    print('a is an empty list')

طعن أمام السلطة

يؤكد PEP 8 ، وهو دليل بيثون الرسمي على طريقة بايثون في مكتبة بايثون القياسية ، على ما يلي:

بالنسبة للتسلسلات ، (السلاسل ، القوائم ، المجموعات) ، استخدم حقيقة أن التتابعات الفارغة خاطئة.

Yes: if not seq:
     if seq:

No: if len(seq):
    if not len(seq):

ينبغي لنا أن نتوقع أن يكون رمز المكتبة القياسي ذا أداء وصحيحًا قدر الإمكان. لكن لماذا هذه القضية ولماذا نحتاج إلى هذا التوجيه؟

تفسير

كثيرا ما أرى رمز مثل هذا من المبرمجين ذوي الخبرة الجديدة لبيثون:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

وقد يميل مستخدمو اللغات البطيئة إلى القيام بذلك:

if a == []:                         # Don't do this!
    print('a is an empty list')

هذه صحيحة في لغاتها الأخرى. وهذا صحيح بشكل دلالي في بايثون.

ولكننا نعتبرها غير بيثونية لأن بايثون تدعم هذه الدلالات مباشرة في واجهة كائن القائمة عبر الإكراه المنطقي.

من docs (ولاحظ على وجه التحديد إدراج القائمة الفارغة ، [] ):

بشكل افتراضي ، يتم اعتبار كائن حقيقي ما لم يعرّف الفئة الخاصة به طريقة __bool__() التي تقوم بإرجاع False أو طريقة __len__() التي تقوم بإرجاع صفر ، عند استدعائها مع الكائن. في ما يلي معظم الأشياء المضمنة التي تعتبر خاطئة:

  • ثوابت محددة لتكون خاطئة: None False .
  • صفر من أي نوع رقمي: 0 ، 0.0 ، 0j ، Decimal(0) ، Fraction(0, 1)
  • تسلسلات ومجموعات فارغة: '' ، () ، [] ، {} ، set() ، range(0)

ووثائق datamodel:

object.__bool__(self)

دعا إلى تنفيذ اختبار قيمة الحقيقة و bool() العملية المضمنة bool() ؛ يجب أن ترجع False أو True . عندما لا يتم تعريف هذه الطريقة ، يتم __len__() ، إذا تم تعريفها ، ويتم اعتبار الكائن صحيحًا إذا كانت نتيجه غير صفرية. إذا كان الفصل الدراسي لا يعرف __len__() ولا __bool__() ، فإن جميع __bool__() تعتبر صحيحة.

و

object.__len__(self)

دعا إلى تنفيذ وظيفة المدمج في len() . يجب إرجاع طول الكائن ، عدد صحيح> = 0. كذلك ، يعتبر الكائن الذي لا يعرف طريقة __bool__() والتي __len__() طريقة __len__() الصفر أنها خاطئة في سياق منطقي.

لذلك بدلا من هذا:

if len(a) == 0:                     # Don't do this!
    print('a is an empty list')

أو هذا:

if a == []:                     # Don't do this!
    print('a is an empty list')

افعل هذا:

if not a:
    print('a is an empty list')

إن أداء ما هو بيثونيك عادة ما يؤتي ثماره في الأداء:

هل تؤتي ثمارها؟ (لاحظ أن الوقت أقل لأداء عملية مكافئة أفضل :)

>>> import timeit
>>> min(timeit.repeat(lambda: len([]) == 0, repeat=100))
0.13775854044661884
>>> min(timeit.repeat(lambda: [] == [], repeat=100))
0.0984637276455409
>>> min(timeit.repeat(lambda: not [], repeat=100))
0.07878462291455435

بالنسبة إلى المقياس ، إليك تكلفة استدعاء الوظيفة وإنشاء قائمة فارغة وإعادتها ، والتي قد تطرحها من تكاليف عمليات الفحص الفارغة المستخدمة أعلاه:

>>> min(timeit.repeat(lambda: [], repeat=100))
0.07074015751817342

ونرى أن إما التحقق من الطول باستخدام دالة len مقارنة بـ 0 أو التحقق من قائمة فارغة أقل بكثير من استخدام بناء الجملة المدمج للغة كما هو موثق.

لماذا ا؟

لـ len(a) == 0 تحقق:

يجب على First Python التحقق من globals لمعرفة ما إذا كان len مظللًا.

ثم يجب أن تستدعي الوظيفة ، وتحميل 0 ، وتقوم بمقارنة المقارنة في بايثون (بدلاً من C):

>>> import dis
>>> dis.dis(lambda: len([]) == 0)
  1           0 LOAD_GLOBAL              0 (len)
              2 BUILD_LIST               0
              4 CALL_FUNCTION            1
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               2 (==)
             10 RETURN_VALUE

وبالنسبة لـ [] == [] ، يجب أن تبني قائمة غير ضرورية ، ثم تقوم مرة أخرى بإجراء عملية المقارنة في جهاز بيثون الافتراضي (في مقابل C)

>>> dis.dis(lambda: [] == [])
  1           0 BUILD_LIST               0
              2 BUILD_LIST               0
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE

الطريقة "Pythonic" هي عملية تحقق أبسط وأسرع حيث أن طول القائمة يتم تخزينه مؤقتًا في عنوان مثيل الكائن:

>>> dis.dis(lambda: not [])
  1           0 BUILD_LIST               0
              2 UNARY_NOT
              4 RETURN_VALUE

دليل من مصدر C والوثائق

PyVarObject

هذا امتداد ل PyObject يضيف المجال ob_size . يستخدم هذا فقط للكائنات التي تحتوي على بعض فكرة الطول. لا يظهر هذا النوع غالبًا في واجهة برمجة تطبيقات Python / C. يقابل الحقول المعرّفة بواسطة توسيع الماكرو PyObject_VAR_HEAD .

من المصدر c في Include/listobject.h :

typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size

لقد استمتعت بالبحث في هذا الأمر وأقضي الكثير من الوقت في تنظيم إجاباتي. إذا كنت تعتقد أنني تركت شيئًا ما ، فالرجاء إخباري بذلك في تعليق.


لماذا تحقق على الإطلاق؟

يبدو أن لا أحد قد عالج تساؤلات حول حاجتك لاختبار القائمة في المقام الأول. نظرًا لأنك لم تقدم أي سياق إضافي ، يمكنني تخيل أنك قد لا تحتاج إلى إجراء هذا التحقق في المقام الأول ، ولكنك غير معتاد على معالجة القائمة في Python.

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

a = []

for item in a:
    <do something with item>

<rest of code>

هذا له فائدة من التعامل مع أي محتويات ، في حين لا تتطلب فحص محدد للفراغ. إذا كان فارغًا ، فلن يتم تنفيذ الكتلة التابعة وسيسقط المترجم خلال السطر التالي.

إذا كنت بحاجة بالفعل إلى التحقق من الصفوف من أجل الفراغ ، فإن الإجابات الأخرى كافية.


الطريقة المثالية للقيام بذلك هي من دليل نمط PEP 8 (حيث يعني نعم "موصى به" ولا يعني "غير مستحسن"):

بالنسبة للتسلسلات ، (السلاسل ، القوائم ، المجموعات) ، استخدم حقيقة أن التتابعات الفارغة خاطئة.

Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):

انا افضل ما يلي:

if a == []:
   print "The list is empty."

للقراءة ولا داعي للقلق بشأن استدعاء دالة مثل len() للتكرار خلال المتغير. على الرغم من أنني لست متأكداً تماماً من أن تدوين "بيغ أو" لشيء من هذا القبيل هو ... لكن بايثون السريع للغاية ، أشك في أنه سيكون مهمًا ما لم يكن a هائلاً.


بعض الطرق التي أستخدمها:

if not a:
    print "list is empty"


if len(a) == 0:
    print "list is empty"

تعتبر القائمة الفارغة نفسها خطأ في اختبار القيمة الحقيقية (انظر وثائق python ):

a = []
if a:
     print "not empty"

@ دارن توماس

تعديل: نقطة أخرى ضد اختبار القائمة الفارغة على أنها خطأ: ماذا عن تعدد الأشكال؟ لا يجب أن تعتمد على القائمة كونها قائمة. يجب أن يكون مجرد دجال مثل البطة - كيف ستحصل على duckCollection إلى الدجال '' False '' عندما لا تحتوي على عناصر؟

يجب أن تنفذ __nonzero__ أو __len__ إذا كان a: سيعمل بدون مشاكل.


طريقة بسيطة هي التحقق من طول تساوي صفر.

if len(a) == 0:
    print("a is empty")

في ما يلي بعض الطرق التي يمكنك من خلالها التحقق مما إذا كانت القائمة فارغة:

a = [] #the list

1) طريقة pythonic بسيطة جدا:

if not a:
    print("a is empty")

في بايثون ، تعتبر الحاويات الفارغة مثل القوائم ، المجموعات ، المجموعات ، dicts ، المتغيرات ، الخ. يمكن للمرء ببساطة التعامل مع القائمة كمسند ( إرجاع قيمة منطقية ). وتشير القيمة True إلى أنها غير فارغة.

2) طريقة واضحة جدًا: باستخدام len() للعثور على الطول والتحقق مما إذا كان يساوي 0 :

if len(a) == 0:
    print("a is empty")

3) أو مقارنتها بقائمة فارغة مجهولة المصدر:

if a == []:
    print("a is empty")

4) طريقة أخرى سخيفة حتى الآن هي استخدام exception و iter() :

try:
    next(iter(a))
    # list has elements
except StopIteration:
    print("Error: a is empty")

لقد رأيت أدناه على النحو المفضل:

if not a:
    print("The list is empty or null")

مستوحاة من حل @ dubiousjim ، أقترح استخدام فحص عام إضافي من ما إذا كان أمرًا ممكنًا أم لا

import collections
def is_empty(a):
    return not a and isinstance(a, collections.Iterable)

ملاحظة: تعتبر السلسلة قابلة للتكرار. - إضافة and not isinstance(a,(str,unicode)) إذا كنت تريد استبعاد السلسلة الفارغة

اختبار:

>>> is_empty('sss')
False
>>> is_empty(555)
False
>>> is_empty(0)
False
>>> is_empty('')
True
>>> is_empty([3])
False
>>> is_empty([])
True
>>> is_empty({})
True
>>> is_empty(())
True

يمكنك حتى محاولة استخدام bool () مثل هذا

    a = [1,2,3];
    print bool(a); # it will return True
    a = [];
    print bool(a); # it will return False

أنا أحب هذه الطريقة لفحص القائمة فارغة أم لا.

مفيد جدا ومفيد.



إذا كنت تريد التحقق مما إذا كانت القائمة فارغة أم لا ؛

def empty_list(lst):
    if len(lst) ==0:
        return false
    else:
        return all(bool(x) for x in l)

إذا كنت تريد أن تتحقق من الطقس ، تكون جميع القيم في القائمة فارغة.

if empty_list(lst):
    # do your stuff.

ومع ذلك سيكون هذا صحيحًا بالنسبة للقائمة الفارغة.

print('not empty' if a else 'empty')

الآن يمكنك استخدام:

a.pop() if a else None

انظر إلى الشفرة التالية التي تم تنفيذها على محطة بايثون التفاعلية.

 >>> a = [] >>> if a: ... print "List is not empty"; ... else: ... print "List is empty" ... List is empty >>> >>> a = [1, 4, 9] >>> if a: ... print "List is not empty"; ... else: ... print "List is empty" ... List is not empty >>> 

جواب باتريك (مقبول) هو الصحيح: if not a: هو الطريق الصحيح للقيام بذلك. رد هارلي هولكومب هو الصحيح أن هذا هو في دليل نمط PEP 8. ولكن ما لا تشرحه الأجوبة هو السبب في أنه من الجيد اتباع المصطلح - حتى لو كنت شخصياً تجد أنه غير واضح بما فيه الكفاية أو مربكًا لمستخدمي Ruby أو أيًا كان.

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

صحيح أنه if not a: لا يميز القوائم الفارغة من بلا ، أو رقمية 0 ، أو المجموعات الفارغة ، أو أنواع مجمعة فارغة أنشأها المستخدم ، أو أنواع فارغة لم يتم جمعها من قبل المستخدم ، أو صفيف NumPy أحادي العنصر يتصرفون كقياسيين ذوي قيم زائفة ، إلخ. وأحيانًا يكون من المهم أن تكون صريحًا بشأن ذلك. وفي هذه الحالة ، أنت تعرف ما تريد أن تكون صريحًا بشأنه ، لذا يمكنك اختبار ذلك بالضبط. على سبيل المثال ، if not a and a is not None: كلمة "أ" ولا "لا شيء" if not a and a is not None: تعني "أي شيء زائف باستثناء بلا" ، أما if len(a) != 0: تعني "التسلسلات الفارغة فقط - وأي شيء غير التسلسل هو خطأ هنا" وهكذا . بالإضافة إلى اختبار ما تريد اختباره بالضبط ، يشير هذا أيضًا إلى أن هذا الاختبار مهم.

ولكن عندما لا يكون لديك أي شيء يكون واضحًا بشأنه ، فإن أي شيء بخلاف if not a: هو تضليل القارئ. أنت تشير إلى شيء مهم عندما لا يكون كذلك. (يمكنك أيضًا جعل الشفرة أقل مرونة ، أو أبطأ ، أو أيا كان ، ولكن هذا أقل أهمية). وإذا كنت تضلل بشكل معتاد القارئ على هذا النحو ، فعندما تكون بحاجة إلى التمييز ، سوف تمر دون أن يلاحظها أحد كنت "تبكي الذئب" في جميع أنحاء التعليمات البرمجية الخاصة بك.


من python3 فصاعدا يمكنك استخدامها

 a = []
 try:
  print(a[-1])
 except IndexError:
  print("List is empty")

للتحقق مما إذا كانت القائمة فارغة

تحرير: هذا يعمل مع python2.7 أيضا ..

لست متأكدًا من سبب وجود العديد من الإجابات المعقدة. انها واضحة ومباشرة


تكون قيمة الحقيقة لقائمة فارغة في حالة وجود قائمة Falseغير فارغة True.


لقد تم إعطاء العديد من الإجابات ، والكثير منها جيد جدًا. أنا فقط أريد أن أضيف أن الاختيار

not a

سوف تمر أيضا Noneلأنواع أخرى من الهياكل الفارغة. إذا كنت تريد حقًا البحث عن قائمة فارغة ، فيمكنك القيام بذلك:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")

a == []

أكثر قليلا من الناحية العملية:

def is_empty(any_structure):
    if any_structure:
        print('Structure is not empty.')
        return True
    else:
        print('Structure is empty.')
        return False  

def list_test (L):
    if   L is None  : print 'list is None'
    elif not L      : print 'list is empty'
    else: print 'list has %d elements' % len(L)

list_test(None)
list_test([])
list_test([1,2,3])

في بعض الأحيان يكون من الجيد اختبار None والفراغ بشكل منفصل لأن هاتين الحالتين مختلفتين. ينتج الرمز أعلاه الإخراج التالي:

list is None 
list is empty 
list has 3 elements

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

def list_test2 (L):
    if not L      : print 'list is empty'
    else: print 'list has %d elements' % len(L)

list_test2(None)
list_test2([])
list_test2([1,2,3])

تنتج المتوقع

list is empty
list is empty
list has 3 elements






is-empty