سؤال

لدي سلسلة من صفوف بايثون التي تمثل الإحداثيات:

tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]

أريد إنشاء القائمة التالية:

l = []
for t in tuples:
  l[ t[0] ][ t[1] ] = something

أحصل على خطأ في الفهرس:فهرس القائمة خارج النطاق.

خلفيتي في PHP وتوقعت أنه في Python يمكنك إنشاء قوائم تبدأ بـ Index> 0، أي.اصنع فجوات ثم املأها، لكن يبدو أنك لا تستطيع ذلك.

والفكرة هي أن يتم فرز القوائم بعد ذلك.أعلم أنه يمكنني القيام بذلك باستخدام القاموس، لكن على حد علمي لا يمكن فرز القواميس حسب المفاتيح.تحديث:أعلم الآن أنهم يستطيعون رؤية الحل المقبول.

يحرر:ما أريد القيام به هو إنشاء مصفوفة ثنائية الأبعاد تمثل المصفوفة الموصوفة بإحداثيات المجموعة، ثم كررها بالترتيب.إذا استخدمت قاموسًا، فليس لدي أي ضمان بأن التكرار على المفاتيح سيكون بالترتيب -> (0,0) (0,1) (0,2) (1,0) (1,1) (1,2) ) (2,0) (2,1) (2,2)

هل أستطيع مساعدتك؟

هل كانت مفيدة؟

المحلول

وماذا تقصد بالضبط من قبل "ولكن بقدر ما أعرف القواميس لا يمكن فرز بواسطة مفاتيح"؟

ورغم أن هذا ليس بدقة نفس "القاموس فرزها"، ل<م> يمكن بسهولة تحويل القاموس إلى القائمة، التي تم فرزها حسب مفتاح، والتي يبدو أن ما كنت بعد:

>>> tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
>>> l = {}
>>> for t in tuples:
...    l[t] = "something"
>>> sorted(l) # equivalent to sorted(l.keys())
[(0, 0), (0, 1), (1, 0), (1, 1), (2, 1)]
>>> sorted(l.items()) # make a list of (key, value) tuples, and sort by key
[((0, 0), 'something'), ((0, 1), 'something'), ((1, 0), 'something'), ((1, 1), 'something'), ((2, 1), 'something')]    

(والتفت something في سلسلة "شيء" فقط لجعل عمل كود)

لجعل استخدام هذه لقضيتك ولكن (إذا فهمت بشكل صحيح، وهذا هو)، وكنت لا تزال بحاجة لملء القاموس مع القيم بلا أو شيء لكل "فارغة" تنسيق الصفوف (tuple))

نصائح أخرى

لا، لا يمكنك إنشاء قائمة بها فجوات.ولكن يمكنك إنشاء قاموس باستخدام مفاتيح Tuple:

tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
l = {}
for t in tuples:
    l[t] = something

تحديث:جرب استخدام NumPy, فهو يوفر نطاقًا واسعًا من العمليات على المصفوفات والمصفوفات.استشهد من ملف pfd المجاني على NumPy المتوفر على الموقع (3.4.3 فهرسة التكرار المسطح): "كما ذكرنا سابقًا، يُرجع X.flat مُكرِّرًا سيتكرر على المصفوفة بأكملها (بنمط C المتجاور مع اختلاف الفهرس الأخير بشكل أسرع".يبدو أن ما تحتاجه.

ويجب أن ننظر في dicts عن شيء من هذا القبيل.

for t in tuples:
  if not l.has_key(t[0]):
    l[t[0]] = {}
  l[t[0]][t[1]] = something

وبالتكرار عبر ديكت يختلف قليلا من بالتكرار عبر قائمة، وإن كان. سيكون لديك مفاتيح () القيم () وحدات () وظائف للمساعدة في ذلك.

وتحرير: حاول شيئا من هذا القبيل للطلب:

for x in sorted(l.keys()):
   for y in sorted(l[x].keys()):
       print l[x][y]

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

لديك الخيارات التالية: إنشاء الخريطة واستخدام ر الصفوف (tuple) كما الفهرس:

l = {}
l[t] = something

وستحصل على الإدخالات في لتر على النحو التالي:

{(1, 1): something}

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

وكما ذكرت استخدام نمباي،

ومع نمباي يمكنك إنشاء مجموعة 2-الأبعاد، وشغل مع الأصفار أو تلك أو ... ثا يمكنك ملء أي القيمة المطلوبة مع فهرسة [س، ص] كما تريدها. بالطبع يمكنك تكرار عبر الصفوف والأعمدة أو مجموعة كاملة كقائمة.

إذا كنت تعرف حجم ما قبل متناول اليد، يمكنك تقديم قائمة من القوائم مثل هذا

>>> x = 3
>>> y = 3
>>> l = [[None] * x for i in range(y)]
>>> l
[[None, None, None], [None, None, None], [None, None, None]]

والتي يمكنك بعد ذلك تكرار مثل اقترحتم أصلا.

الجواب ناثان الصورة،

tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
x = max(tuples, key = lambda z : z[0])[0] + 1
y = max(tuples, key = lambda z : z[1])[1] + 1
l = [[None] * y for i in range(x)]

وبعد ذلك يمكنك أن تفعل ما تريد

وكما ذكر سابقا، لا يمكن أن تجعل القوائم مع وجود ثغرات، وربما يكون القواميس الخيار الأفضل هنا. الحيلة هي أن يتأكد أن l[t[0]] موجود عند وضع شيء في موقف t[1]. لهذا، كنت تستخدم defaultdict .

import collections
tuples = [(1,1), (0,1), (1,0), (0,0), (2,1)]
l = collections.defaultdict(dict)
for t in tuples:
    l[t[0]][t[1]] = something

ومنذ l هو defaultdict، إذا لم يكن موجودا l[t[0]]، فإنه سيتم إنشاء ديكت فارغة بالنسبة لك لوضع something بك في في موقف t[1].

ملحوظة: هذا ينتهي به الأمر إلى نفس @ unwesen في الجواب، دون ملل طفيفة من اليد فحص لوجود ديكت الداخلي. الطباشير ليصل إلى الرد المتزامنة.

والحلول ديكت المعطاة هي على الأرجح أفضل لمعظم الأغراض. لمشكلتك من بالتكرار عبر المفاتيح في النظام، عموما كنت بدلا تكرار عبر <م> تنسيق الفضاء ، وليس مفاتيح ديكت، بنفس الطريقة سيكون لديك لقائمة من القوائم. استخدام. احصل على ويمكنك تحديد القيمة الافتراضية لاستخدام للخلايا فارغة، أو استخدام "collections.defaultdict" لتحديد الافتراضي في وقت إنشاء ديكت بدلا من ذلك. على سبيل المثال.

for y in range(10):
    for x in range(10):
        value = mydict.get((x,y), some_default_value)
        # or just "value = mydict[x,y]" if used defaultdict

إذا كنت بحاجة إلى قائمة الفعلية من القوائم، يمكنك بناء مباشرة على النحو التالي:

max_x, max_y = map(max, zip(*tuples))
l=[[something if (x,y) in tuples else 0 for y in range(max_y+1)] 
     for x in xrange(max_x+1)]

إذا قائمة الصفوف من المرجح أن تكون طويلة، ولأسباب تتعلق بالأداء، قد ترغب في استخدام مجموعة للبحث، و"(x,y) in tuples" ينفذ مسح القائمة، بدلا من البحث السريع عن طريق التجزئة. أي تغيير السطر الثاني إلى:

tuple_set = set(tuples)
l=[[something if (x,y) in tuple_set else 0 for y in range(max_y+1)] 
     for x in xrange(max_x+1)]

وأعتقد أنك قد أعلن سوى قائمة واحدة الأبعاد.

وأعتقد أنك تعلن بأنها

l = [][]

تعديل : في هذا خطأ في بناء جملة

>>> l = [][]
  File "<stdin>", line 1
    l = [][]
           ^
SyntaxError: invalid syntax
>>> 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top