2009-12-12 24 views
246

मैं सोच रहा था कि string सूची को list में परिवर्तित करने का सबसे आसान तरीका क्या है:पायथन में सूची में सूची का स्ट्रिंग प्रतिनिधित्व कनवर्ट करें

x = u'[ "A","B","C" , " D"]' 

यहां तक ​​कि यदि उपयोगकर्ता अल्पविरामों और उद्धरणों के अंदर रिक्त स्थान के बीच स्थान रखता है। मुझे इसे भी संभालना होगा: पायथन में

x = ["A", "B", "C", "D"] 

मुझे पता है कि मैं split ऑपरेटर का उपयोग कर strip() और split() के साथ रिक्त स्थान को स्ट्रिप कर सकता हूं और गैर वर्णमाला के लिए जांच सकता हूं। लेकिन कोड बहुत पतला हो रहा था। क्या कोई त्वरित कार्य है जिसके बारे में मुझे पता नहीं है?

+3

क्या आप वास्तव में पूरा करने के लिए कोशिश कर रहे हैं? पाइथन सूची वाक्यविन्यास को वास्तविक सूची में बदलने की कोशिश करने से शायद एक बेहतर तरीका है ... –

+0

पाइथन का कौन सा संस्करण आप उपयोग कर रहे हैं? –

+2

@ निकोलस नाइट: मैं एक विरासत ऐप में उपयोगकर्ता इनपुट को संभालने की कोशिश कर रहा हूं जहां सभी सूचियों को वर्ग संश्लेषण के साथ यूनिकोड सूचियों के रूप में दर्ज किया गया था। @ मार्क बियर, मैं अजगर 2.6 का उपयोग कर रहा हूं, इसलिए ast.literal दृष्टिकोण सबसे अच्छा काम करता है – harijay

उत्तर

403
>>> import ast 
>>> x = u'[ "A","B","C" , " D"]' 
>>> x = ast.literal_eval(x) 
>>> x 
['A', 'B', 'C', ' D'] 
>>> x = [n.strip() for n in x] 
>>> x 
['A', 'B', 'C', 'D'] 

ast.literal_eval:

ast.literal_eval के साथ, आप सुरक्षित रूप से एक अभिव्यक्ति नोड या अजगर अभिव्यक्ति युक्त एक स्ट्रिंग का मूल्यांकन कर सकते हैं। प्रदान की गई स्ट्रिंग या नोड में केवल निम्नलिखित पायथन शाब्दिक संरचनाएं हो सकती हैं: तार, संख्याएं, ट्यूपल्स, सूचियां, डिब्बे, बूलियन, और कोई भी नहीं।

+2

नीचे प्रति टिप्पणी, यह खतरनाक है क्योंकि यह स्ट्रिंग में जो भी पायथन है, वह बस चलता है। तो अगर कोई वहां सबकुछ हटाने के लिए कॉल करता है, तो यह खुशी से होगा। –

+0

ग्रेट उत्तर, मैंने इस मुद्दे को तब तक एक घंटे तक संघर्ष किया जब तक यह जवाब नहीं मिला। –

5

वहाँ एक त्वरित समाधान है: सूची तत्वों में

x = eval('[ "A","B","C" , " D"]') 

अवांछित व्हाइटस्पेस इस तरह से हटाया जा सकता है:

x = [x.strip() for x in eval('[ "A","B","C" , " D"]')] 
+0

यह अभी भी उद्धरण – tosh

+10

के अंदर की जगहों को संरक्षित रखेगा यह मनमाने ढंग से कोड निष्पादन के लिए एक खुला निमंत्रण है, इसे कभी भी या ऐसा कुछ भी न करें जब तक आप पूर्ण से नहीं जानते निश्चितता कि इनपुट हमेशा 100% भरोसेमंद होगा। –

+0

@tosh: यह नहीं होगा। –

9
import ast 
l = ast.literal_eval('[ "A","B","C" , " D"]') 
l = [i.strip() for i in l] 
50

eval खतरनाक है - आप पर अमल नहीं करना चाहिए उपयोगकर्ता का निवेश।

आप 2.6 या नए हैं, तो eval के बजाय ast का उपयोग करें:

>>> import ast 
>>> ast.literal_eval('["A","B" ,"C" ," D"]') 
["A", "B", "C", " D"] 

एक बार जब आप कि, strip तार किया है।

आप अजगर के एक पुराने संस्करण का उपयोग कर रहे हैं, तो आप बहुत क्या आप एक साधारण नियमित अभिव्यक्ति के साथ चाहते हैं उसके पास प्राप्त कर सकते हैं:

>>> x='[ "A", " B", "C","D "]' 
>>> re.findall(r'"\s*([^"]*?)\s*"', x) 
['A', 'B', 'C', 'D'] 

यह ast समाधान के रूप में के रूप में अच्छा नहीं है, उदाहरण के लिए यह तारों में बच निकले उद्धरण सही ढंग से संभाल नहीं करता है। लेकिन यह आसान है, इसमें एक खतरनाक eval शामिल नहीं है, और यदि आप बिना किसी अस्थिर के पुराने पायथन पर हैं तो अपने उद्देश्य के लिए पर्याप्त हो सकता है।

+0

क्या आप कृपया मुझे बता सकते हैं कि आपने क्यों कहा था "' eval' खतरनाक है - आपको उपयोगकर्ता इनपुट निष्पादित नहीं करना चाहिए। " मैं 3.6 –

+0

@ आर्यन दीवान का उपयोग कर रहा हूं यदि आप सीधे 'eval' का उपयोग करते हैं, तो यह किसी वैध पायथन अभिव्यक्ति का मूल्यांकन करेगा, जो संभावित रूप से खतरनाक है। 'literal_eval' केवल पाइथन शाब्दिक संरचनाओं का मूल्यांकन करके इस समस्या को हल करता है: तार, संख्या, tuples, सूचियों, dicts, बूलियन, और कोई नहीं। –

3

यदि आप जानते हैं कि आपकी सूचियों में केवल उद्धृत तार हैं, तो यह पाइपर्सिंग उदाहरण आपको स्ट्रिप किए गए तारों की सूची (यहां तक ​​कि मूल यूनिकोड-नेस को संरक्षित) भी देगा।

>>> from pyparsing import * 
>>> x =u'[ "A","B","C" , " D"]' 
>>> LBR,RBR = map(Suppress,"[]") 
>>> qs = quotedString.setParseAction(removeQuotes, lambda t: t[0].strip()) 
>>> qsList = LBR + delimitedList(qs) + RBR 
>>> print qsList.parseString(x).asList() 
[u'A', u'B', u'C', u'D'] 

अपनी सूची अधिक डेटाटाइप्स हो सकता है, या यहाँ तक कि सूचियों के भीतर सूचियाँ शामिल है, तो आप एक और अधिक पूरा व्याकरण की आवश्यकता होगी - this one pyparsing विकि पर की तरह है, जो tuples, सूचियों, ints, तैरता संभाल लेंगे, और उद्धृत स्ट्रिंग्स। पाइथन संस्करणों के साथ 2.4 पर काम करेगा।

+0

क्या आप मुझे "parseString()। AsList()" का उपयोग करने के बारे में बताएंगे, अगर मेरे पास इस प्रकार की स्ट्रिंग है: '["ए", "बी", "सी", ["डी"]]', जैसा कि आपने कहा है कि पाइपर्सिंग भी ऐसा कर सकती है। लेकिन ऐसा लगता है कि ऐसा करने का सही तरीका नहीं मिला है। –

+0

"यदि आपकी सूचियों में अधिक डेटाटाइप हो सकते हैं, या सूचियों के भीतर सूचियां भी हो सकती हैं, तो आपको एक और पूर्ण व्याकरण की आवश्यकता होगी" - कृपया मेरे उत्तर में दिए गए लिंक को एक पार्सर के लिए देखें जो नेस्टेड सूचियों को संभालेगा, और कई अन्य डेटा प्रकार । – PaulMcG

7

मान लें कि आपके सभी इनपुट सूचियां हैं और इनपुट में डबल कोट्स वास्तव में कोई फर्क नहीं पड़ता है, यह एक साधारण regexp प्रतिस्थापन के साथ किया जा सकता है। यह थोड़ा perl-y है लेकिन एक आकर्षण की तरह काम करता है।ध्यान दें कि आउटपुट अब यूनिकोड तारों की एक सूची है, आपने यह निर्दिष्ट नहीं किया है कि आपको इसकी आवश्यकता है, लेकिन ऐसा लगता है कि यूनिकोड इनपुट दिया गया है।

import re 
x = u'[ "A","B","C" , " D"]' 
junkers = re.compile('[[" \]]') 
result = junkers.sub('', x).split(',') 
print result 
---> [u'A', u'B', u'C', u'D'] 

JUNKERS चर का उपयोग कर] एक चरित्र के रूप में आवश्यक कुछ बैकस्लैश प्रवंचना, सभी पात्रों हम नहीं चाहते की एक संकलित regexp (गति के लिए) शामिल हैं। re.sub इन सभी वर्णों को कुछ भी नहीं बदलता है, और हम परिणामस्वरूप स्ट्रिंग को अल्पविराम में विभाजित करते हैं।

ध्यान दें कि यह अंदरूनी प्रविष्टियों से रिक्त स्थान भी हटा देता है ['ओह नो "]' ---> [u'ohno ']। यदि यह वही नहीं है जो आप चाहते थे, तो regexp को थोड़ा सा सूप करने की आवश्यकता है।

7
numpy साथ

यह एक बहुत ही आसान तरीका

x = u'[ "A","B","C" , " D"]' 
list_string = str(x) 
import numpy as np 
print np.array(list_string) 

काम कर रहा है देता है

>>> 
[ "A","B","C" , " D"] 
+4

यह काम नहीं करता है। यह बस स्ट्रिंग का 0-डी सरणी बनाता है। किसी तत्व को एक्सेस करने जैसे किसी भी सरणी ऑपरेशन, त्रुटि के साथ विफल। – River

30

json मॉड्यूल एक बेहतर समाधान है जब भी वहाँ है एक शब्दकोशों की सूची stringified। json.loads(your_data) फ़ंक्शन का उपयोग इसे किसी सूची में बदलने के लिए किया जा सकता है।

>>> import json 
>>> x = u'[ "A","B","C" , " D"]' 
>>> json.loads(x) 
[u'A', u'B', u'C', u' D'] 

इसी

>>> x = u'[ "A","B","C" , {"D":"E"}]' 
>>> json.loads(x) 
[u'A', u'B', u'C', {u'D': u'E'}] 
+0

हालांकि मैं यूनिकोड प्रारूप में लौटाई गई सूची नहीं चाहता हूं। लेकिन ऐसा लगता है कि अगर मैं स्ट्रिंग से आपको '' हटा देता हूं, तब भी यह डेटा को यूनिकोड के रूप में मानता है। –

+1

यह इन्ट्स के लिए काम करता है लेकिन मेरे मामले में तारों के लिए नहीं है क्योंकि प्रत्येक स्ट्रिंग को सिंगल उद्धृत नहीं किया गया है, जो कि उद्धृत नहीं है। –

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