2009-10-25 19 views
9

में काम नहीं करता मैं उत्पादन एक स्वरूपित सूची में प्रतिस्थापन क्षेत्र में एक नकारात्मक सूचकांक का उपयोग करें, लेकिन यह उठता है एक TypeError.The कोड इस प्रकार हैं:str.format (सूची) नकारात्मक सूचकांक के साथ अजगर

 
>>> a=[1,2,3] 
>>> a[2] 
3 
>>> a[-1] 
3 
>>> 'The last:{0[2]}'.format(a) 
'The last:3' 
>>> 'The last:{0[-1]}'.format(a) 
Traceback (most recent call last): 
    File "", line 1, in 
TypeError: list indices must be integers, not str 
+0

प्रारूप फ़ंक्शन परिभाषा में एक निरीक्षण की तरह लगता है – barkmadley

+2

पायथन के बगबेस में प्रासंगिक बग - http://bugs.python.org/issue7951। संक्षेप में, इस मुद्दे को लागू करने के दुष्प्रभावों के कारण इस मुद्दे को एक दस्तावेज बग के रूप में माना जा रहा है और यह भी तथ्य कि इससे खराब कोड हो सकता है। – Sam

उत्तर

12

यह है कि मैं प्रारूप स्ट्रिंग चश्मे में एक डिजाइन गड़बड़ कहूंगा। प्रति the docs,

element_index  ::= integer | index_string 

लेकिन, अफसोस, -1 "एक पूर्णांक" नहीं है - यह एक अभिव्यक्ति है। यूनरी-माइनस ऑपरेटर में विशेष रूप से उच्च प्राथमिकता भी नहीं होती है, उदाहरण के लिए print(-2**2)-4 उत्सर्जित करता है - एक और आम समस्या और तर्कसंगत रूप से एक डिज़ाइन गड़बड़ (** ऑपरेटर की उच्च प्राथमिकता होती है, इसलिए raise-शक्ति-शक्ति पहले होती है, फिर निम्न प्राथमिकता unary - द्वारा अनुरोधित परिवर्तन-चिह्न)।

प्रारूप स्ट्रिंग कि एक पूर्णांक (एक अभिव्यक्ति लेकिन, उदाहरण के लिए,) नहीं है में उस स्थिति में कुछ भी, एक dict तर्क स्ट्रिंग के रूप में व्यवहार किया जाता सूचकांक करने के लिए - उदाहरण के लिए:

$ python3 -c "print('The last:{0[2+2]}'.format({'2+2': 23}))" 
The last:23 
नहीं

यकीन । क्या यह अजगर Trac में कोई समस्या उठाकर लायक है, लेकिन यह निश्चित रूप से एक कुछ आश्चर्य की बात व्यवहार है :-(

+0

दिलचस्प! -2 -2 के बराबर -4 के बराबर होने के नाते, मुझे लगता है कि यह एक बहुत अच्छी बात है, क्योंकि यह गणित में उपयोग किया जाने वाला सम्मेलन है। क्या element_index :: = "sign_integer" की तरह कुछ समझ में आता है? – EOL

1

वहाँ कुछ समस्याओं यहाँ, एक बार आप खुदाई शुरू कर रहे हैं:

संबंधित आइटम पर कहा जाता है " element_index "जिसे पूर्णांक माना जाता है।

समस्या 1: जब तक उपयोगकर्ता भाषा संदर्भ मैनुअल में "पूर्णांक" से लिंक का पालन नहीं करते हैं, वे नहीं जानते कि -1 को एक अभिव्यक्ति माना जाता है, पूर्णांक नहीं। वैसे, किसी ने "प्रलेखित के रूप में काम करता है" कहने का लुत्फ उठाया, पहले 7 लोगों को देखना चाहिए :-)

पसंदीदा समाधान: परिभाषा को बदलें ताकि "element_index" में पूर्णांक से पहले वैकल्पिक '-' हो।

यह एक पूर्णांक है, है ना? इतना तेज़ नहीं ... बाद में दस्तावेज़ कहते हैं कि "फॉर्म की अभिव्यक्ति" [इंडेक्स] '__getitem__() "

समस्या 3:' [element_index] '(अनुक्रमणिका परिभाषित नहीं है) का उपयोग करना चाहिए।

समस्या 4: हर कोई अपने सिर के शीर्ष से नहीं जानता कि __getitem__() करता है। स्पष्ट दस्तावेज़ों की आवश्यकता है।

तो हम यहाँ एक धक्का के साथ-साथ एक पूर्णांक का उपयोग कर सकते हैं, क्या हम कर सकते हैं? हां, एक समस्या या दो के साथ:

element_index एक पूर्णांक है? हाँ, वह एक dict के साथ काम करता है:

>>> "{0[2]}".format({2: 'int2'}) 
'int2' 

ऐसा लगता है कि हम भी गैर पूर्णांक तार का उपयोग कर सकते हैं, लेकिन यह अधिक स्पष्ट प्रलेखन की जरूरत है (समस्या 5):

>>> "{0[foo]}".format({'foo': 'bar'}) 
'bar' 

लेकिन हम नहीं कर सकते '2' (समस्या 6) की तरह एक कुंजी के साथ एक dict का उपयोग करें:

>>> "{0[2]}".format({'2': 'str2'}) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: 2 
>>> "{0['2']}".format({'2': 'str2'}) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: "'2'" 

समस्या 7: "पूर्णांक" वास्तव में "decimalinteger" होने के लिए प्रलेखित किया जाना चाहिए यही कारण है कि ...0x22 और 0b11 str के रूप में इलाज कर रहे हैं, और 010 (एक "octalinteger"), 10 के रूप में व्यवहार किया जाता है 8 नहीं:

>>> "{0[010]}".format('abcdef') 
'a' 

अद्यतन:
"" "
नियम:
PEP 3101 सच्ची कहानी बताता है किसी आइटम कुंजी को पार्स करने के लिए बहुत सरल होता है। यदि यह अंक से शुरू होता है, तो इसे एक संख्या के रूप में माना जाता है, अन्यथा इसे स्ट्रिंग के रूप में उपयोग किया जाता है।

क्योंकि कुंजी उद्धरण-सीमित नहीं हैं, इसलिए निर्दिष्ट करना संभव नहीं है मनमानी शब्दकोश कुंजी (उदाहरण के लिए, स्ट्रिंग्स "10" या ": -]") प्रारूप स्ट्रिंग के भीतर से।
""

1

सही, यह काम नहीं करता है। समाधान:

>>> 'The last:{0}'.format(a[-1]) 
'The last:3' 
+1

जो सवाल पूछता है: तो क्यों सीमित अनुक्रम अनुक्रमण, प्रतिबंधित निर्देश लुकअप, और फॉर्मेट स्ट्रिंग में विशेषता लुकअप सुविधाओं को डिज़ाइन करने से परेशान है, जब तर्क में सभी और अधिक किए जा सकते हैं? –

+0

हाँ, मुझे धड़कता है। –

0

मैं अक्सर config विकल्प के रूप में अजगर प्रारूप तार ले - कीवर्ड तर्क का एक विशिष्ट, जाना जाता सूची के साथ प्रदान की प्रारूप स्ट्रिंग के साथ। इसलिए प्रारूप स्ट्रिंग के भीतर आगे या पीछे एक परिवर्तनीय लंबाई सूची के इंडेक्स को संबोधित करना बिल्कुल ठीक है जिसकी मुझे आवश्यकता है।

मैं सिर्फ नकारात्मक अनुक्रमण काम करने के लिए इस हैक लिखा है:

string_to_tokenise = "Hello_world" 
tokens = re.split(r"[^A-Z\d]+", string_to_tokenise, flags=re.I) 
token_dict = {str(i) if i < 0 else i: tokens[i] for i in range(-len(tokens) + 1, len(tokens))} 
print "{thing[0]} {thing[-1]}".format(thing=token_dict) 

परिणाम:

Hello world 

तो समझाने के लिए, बजाय टोकन की सूची में से गुजर रहा है, मैं बनाने के एक 0 से लेन (..) - 1 से सूची अनुक्रमणित करने के लिए सभी आवश्यक पूर्णांक कुंजी के साथ शब्दकोश, और मैं -1 से लेकर (लेन (..) - 1) के अंत से अनुक्रमण के लिए नकारात्मक पूर्णांक कुंजी भी जोड़ता हूं, हालांकि इन चाबियों को पूर्णांक से तारों में परिवर्तित कर दिया जाता है, क्योंकि इस तरह प्रारूप उन्हें व्याख्या करेगा।

संबंधित मुद्दे