স্ট্রিংয়ের উপস্থাপনাকে কীভাবে তালিকায় রূপান্তর করবেন?


530

আমি ভাবছিলাম যে সহজ উপায়টি stringনিম্নলিখিতগুলির মতো একটি তালিকাতে রূপান্তর করার জন্য কী list:

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

এমনকি ব্যবহারকারী কমাগুলির মধ্যে ফাঁকা স্থান এবং কোটের ভিতরে ফাঁকা রাখে। আমারও এটি পরিচালনা করতে হবে:

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

পাইথনে।

আমি জানি যে আমি স্প্লিট অপারেটরটি ব্যবহার করে strip()এবং split()ব্যবহার করে ফাঁকা স্থানগুলি তৈরি করতে এবং নন বর্ণমালা পরীক্ষা করতে পারি। কিন্তু কোডটি খুব ক্লডজি হচ্ছিল। এমন কোন দ্রুত কার্যকারিতা আছে যা সম্পর্কে আমি অবগত নই?


4
আপনি আসলে কী অর্জন করার চেষ্টা করছেন? পাইথন তালিকার সিনট্যাক্সকে প্রকৃত তালিকায় রূপান্তরিত করার চেষ্টা করার চেয়ে আরও ভাল উপায় সম্ভবত রয়েছে ...
নিকোলাস নাইট

1
পাইথনের কোন সংস্করণ আপনি ব্যবহার করছেন?
মার্ক বাইয়ার্স

2
@ নিকোলাস নাইট: আমি এমন একটি লিগ্যাসি অ্যাপ্লিকেশনটিতে ব্যবহারকারীর ইনপুট হ্যান্ডেল করার চেষ্টা করছি যেখানে সমস্ত তালিকা বর্গক্ষেত্রের সাথে ইউনিকোড তালিকা হিসাবে প্রবেশ করানো হয়েছিল। @ মার্ক বাইয়ার্স, আমি পাইথন ২.6 ব্যবহার করছি যাতে অ্যাস্ট.লাইটেরাল পদ্ধতিটি সর্বোত্তমভাবে কাজ করে
হরিজেয়

উত্তর:


768
>>> 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 এর সাহায্যে আপনি কোনও এক্সপ্রেশন নোড বা পাইথন এক্সপ্রেশন যুক্ত স্ট্রিংটি নিরাপদে মূল্যায়ন করতে পারেন। সরবরাহ করা স্ট্রিং বা নোডে কেবলমাত্র পাইথনের আক্ষরিক কাঠামোগুলি থাকতে পারে: স্ট্রিং, সংখ্যা, টিপলস, তালিকা, ডিক্টস, বুলিয়ান এবং কোনও নয়।


6
নীচের মন্তব্য অনুসারে, এটি বিপজ্জনক কারণ এটি অজগর স্ট্রিংয়ের যা কিছু রয়েছে কেবল তা চালায়। সুতরাং কেউ যদি সেখানে থাকা সমস্ত কিছু মুছতে কল দেয় তবে তা আনন্দের সাথে হবে।
পল কেনজোরা 21

16
@ পলকেনজোরা: আপনি evalনা, তা নিয়ে ভাবছেন ast.literal_eval
ব্যবহারকারী 2357112 23-29 তে মনিকা

19
ast.literal_evalএর চেয়ে নিরাপদeval তবে এটি আসলে নিরাপদ নয়ডক্সের সাম্প্রতিক সংস্করণগুলি যেমন ব্যাখ্যা করেছে: "সতর্কতা পাইথনের এএসটি সংকলকটিতে গভীরতার সীমাবদ্ধতার কারণে যথেষ্ট বড় / জটিল স্ট্রিং দিয়ে পাইথন ইন্টারপ্রেটারকে ক্রাশ করা সম্ভব" " প্রকৃতপক্ষে, সাবধানে স্ট্যাক-স্ম্যাশিং আক্রমণের মাধ্যমে স্বেচ্ছাসেবীর কোড চালানো সম্ভব হতে পারে, যদিও আমি জানি যতদিন না কারও পক্ষে এর পক্ষে ধারণার সার্বজনীন প্রমাণ তৈরি করা সম্ভব নয়।
অবতরণ

ঠিক আছে তবে তালিকায় কোট না থাকলে কী করব? যেমন [বি এর 4, জি এর 1]
sqp_125

84

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'}]

তবে আমি ইউনিকোড ফর্ম্যাটে ফিরে আসা তালিকাটি চাই না। তবে মনে হচ্ছে এমনকি যদি আমি স্ট্রিং থেকে আপনার '' অপসারণ করি তবে এটি স্থির করে দিয়ে ডেটাটিকে ইউনিকোড হিসাবে গণ্য করে।
মনসুর আকরাম

7
এটি ints জন্য কাজ করে তবে আমার ক্ষেত্রে স্ট্রিংয়ের জন্য নয় কারণ প্রতিটি স্ট্রিং এককভাবে উদ্ধৃত নয় ডাবল কোটেড, দীর্ঘশ্বাস ফেলে।
পল কেনজোরা 21

4
@ পলকেনজোরার মন্তব্য অনুসারে, এটি কাজ করে '["a","b"]'তবে পক্ষে না "['a','b']"
স্কিপি লে গ্র্যান্ড গৌরু

83

evalবিপজ্জনক - আপনি ব্যবহারকারীর ইনপুট চালানো উচিত নয়।

আপনার যদি ২.6 বা তার থেকেও বেশি নতুন থাকে তবে অ্যাভালের পরিবর্তে অ্যাস্ট ব্যবহার করুন:

>>> 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']

এটি অ্যাস্ট সমাধানের মতো উত্তম নয়, উদাহরণস্বরূপ এটি স্ট্রিংগুলিতে পালিয়ে যাওয়া উদ্ধৃতিগুলি সঠিকভাবে পরিচালনা করে না। তবে এটি সহজ, কোনও বিপজ্জনক ইওল জড়িত না এবং আপনি যদি অস্ট না করে কোনও পুরানো পাইথনে থাকেন তবে আপনার উদ্দেশ্যটির পক্ষে এটি যথেষ্ট ভাল।


আপনি দয়া করে আমাকে বলতে পারেন কেন আপনি কেন বলেছেন " evalএটি বিপজ্জনক - আপনার ব্যবহারকারীর ইনপুটটি কার্যকর করা উচিত নয়?" আমি 3.6 ব্যবহার করছি
আরিয়ান দেওয়ান

1
@ আর্যান দেওয়ান আপনি যদি evalসরাসরি ব্যবহার করেন তবে এটি কোনও বৈধ পাইথন অভিব্যক্তি মূল্যায়ন করবে, এটি সম্ভাব্য বিপজ্জনক। literal_evalকেবল পাইথনের আক্ষরিক কাঠামোর মূল্যায়ন করে এই সমস্যাটি সমাধান করে: স্ট্রিংস, সংখ্যা, টিপলস, তালিকা, ডিক্টস, বুলিয়ান এবং কিছুই নয়।
অভিষেক মেনন


10

একটি দ্রুত সমাধান আছে:

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

তালিকার উপাদানগুলিতে অযাচিত হোয়াইটস্পেসগুলি এভাবে মুছে ফেলা হতে পারে:

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

এটি এখনও কোটের অভ্যন্তরের স্পেসগুলি সংরক্ষণ করবে
টশ করুন

17
এটি নির্বিচারে কোড কার্যকর করার জন্য একটি উন্মুক্ত আমন্ত্রণ, ইনপুটটি সর্বদা 100% বিশ্বাসযোগ্য হবে না এমন আপনি যদি নিশ্চিতভাবে না জানেন তবে এগুলি বা এর মতো কিছু কখনই করবেন না।
নিকোলাস নাইট

1
আমি এই পরামর্শটি ব্যবহার করতে পারি কারণ আমি জানতাম যে আমার ডেটা সর্বদা সেই বিন্যাসে থাকবে এবং এটি একটি ডেটা প্রসেসিংয়ের কাজ ছিল।
মণীশ রঞ্জন

9

বেস পাইথন প্যাকেজগুলির সাথে কাজ করে উপরের কয়েকটি উত্তর থেকে অনুপ্রাণিত হয়ে আমি কয়েকটিটির পারফরম্যান্স তুলনা করেছি (পাইথন ৩.7.৩ ব্যবহার করে):

পদ্ধতি 1: অ্যাস্ট

import ast
list(map(str.strip, ast.literal_eval(u'[ "A","B","C" , " D"]')))
# ['A', 'B', 'C', 'D']

import timeit
timeit.timeit(stmt="list(map(str.strip, ast.literal_eval(u'[ \"A\",\"B\",\"C\" , \" D\"]')))", setup='import ast', number=100000)
# 1.292875313000195

পদ্ধতি 2: json

import json
list(map(str.strip, json.loads(u'[ "A","B","C" , " D"]')))
# ['A', 'B', 'C', 'D']

import timeit
timeit.timeit(stmt="list(map(str.strip, json.loads(u'[ \"A\",\"B\",\"C\" , \" D\"]')))", setup='import json', number=100000)
# 0.27833264000014424

পদ্ধতি 3: কোনও আমদানি নেই

list(map(str.strip, u'[ "A","B","C" , " D"]'.strip('][').replace('"', '').split(',')))
# ['A', 'B', 'C', 'D']

import timeit
timeit.timeit(stmt="list(map(str.strip, u'[ \"A\",\"B\",\"C\" , \" D\"]'.strip('][').replace('\"', '').split(',')))", number=100000)
# 0.12935059100027502

আমি সবচেয়ে খারাপ পাঠযোগ্যতার সাথে পদ্ধতিটি সবচেয়ে ভাল পারফরম্যান্সের সাথে বিবেচনা করে দেখে হতাশ হয়েছি ... সর্বাধিক পঠনযোগ্য বিকল্পের সাথে যাওয়ার সময় বিবেচনা করার মতো ট্রেড অফ রয়েছে ... আমি সাধারণত যে ধরণের কাজের চাপ ব্যবহার করি তার জন্য আমি সাধারণত পাইথন ব্যবহার করি সামান্য আরও পারফরম্যান্ট বিকল্পের উপরে মান পঠনযোগ্যতা, তবে যথারীতি এটি নির্ভর করে।


9

যদি এটি কেবলমাত্র একটি মাত্রিক তালিকা থাকে তবে কিছু আমদানি না করেই এটি করা যেতে পারে:

>>> x = u'[ "A","B","C" , " D"]'
>>> ls = x.strip('[]').replace('"', '').replace(' ', '').split(',')
>>> ls
['A', 'B', 'C', 'D']

8
সতর্কতামূলক দ্রষ্টব্য: তালিকার অভ্যন্তরে থাকা কোনও স্ট্রিংয়ের মধ্যে যদি কমা থাকে তবে এটি সম্ভবত বিপজ্জনক হতে পারে।
হাসান কামাল

আপনার স্ট্রিং তালিকা তালিকার একটি তালিকা হলে এটি কাজ করবে না
ক্রিপডিক

@ ক্রিপডিক গুড পয়েন্ট, সে সম্পর্কে একটি নোট যুক্ত করেছেন :)
রুহোলা

6

ধরে নিই যে আপনার সমস্ত ইনপুট তালিকাগুলি এবং ইনপুটটিতে ডাবল উদ্ধৃতিগুলি আসলে কিছু যায় আসে না, এটি একটি সাধারণ রেজিএক্সপ্লেস প্রতিস্থাপনের মাধ্যমে করা যেতে পারে। এটি কিছুটা পার্ল-ওয়াই তবে মনোযোগের মতো কাজ করে। এও নোট করুন যে আউটপুটটি এখন ইউনিকোড স্ট্রিংগুলির একটি তালিকা, আপনি এটি নির্দিষ্ট করেন নি যে আপনার এটি প্রয়োজন ছিল, তবে ইউনিকোড ইনপুট প্রদত্ত বলে মনে হয়।

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']

জঙ্গার ভেরিয়েবলের মধ্যে আমরা চাই না এমন সমস্ত অক্ষরের একটি সংকলিত রিজেক্সেপ (গতির জন্য) রয়েছে] একটি চরিত্র হিসাবে কিছু ব্যাকস্ল্যাশ ট্র্যাকির প্রয়োজন। রেসসুব এই সমস্ত অক্ষরকে কিছু না করে প্রতিস্থাপন করে এবং ফলস্বরূপ স্ট্রিংটি আমরা কমাতে বিভক্ত করি।

দ্রষ্টব্য যে এটি আপনার প্রবেশদ্বারগুলির ভিতরে 'u "[" ওহ না "]' ---> [u'ohno '] থেকে স্পেসও সরিয়ে ফেলে। আপনি যদি যা চেয়েছিলেন এটি যদি না হয় তবে রেজিএক্সপক্সকে কিছুটা স্যুপ করা দরকার।


4

আপনি যদি জানেন যে আপনার তালিকায় কেবল উদ্ধৃত স্ট্রিং রয়েছে তবে এই পাইপার্সিং উদাহরণটি আপনাকে স্ট্রিপযুক্ত স্ট্রিংগুলির তালিকা দেবে (এমনকি মূল ইউনিকোড-নেস সংরক্ষণ করে)।

>>> 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']

যদি আপনার তালিকাগুলিতে আরও বেশি ডেটাটাইপ থাকতে পারে, বা এমনকি তালিকার মধ্যে তালিকাগুলি থাকতে পারে তবে আপনার আরও একটি সম্পূর্ণ ব্যাকরণ প্রয়োজন হবে - পাইপসিং উইকির মতো এটি , যা টিপলস, তালিকাগুলি, ইনটস, ফ্লোটস এবং উদ্ধৃত স্ট্রিংগুলি পরিচালনা করবে। পাইথনের সংস্করণগুলি ২.৪-এ ফিরে আসবে।


আপনি যদি আমাকে "পার্সস্ট্রিং ()। asList ()" কীভাবে ব্যবহার করতে চান, যদি আমার কাছে এই জাতীয় স্ট্রিং থাকে: '["এ", "বি", "সি", ["ডি"]]', আপনি যেমন বলেছে যে পাইপার্সিং এটিও করতে পারে। তবে ও এটি করার সঠিক উপায় খুঁজে পেয়েছে বলে মনে হয় না।
মনসুর আকরাম

"যদি আপনার তালিকাগুলিতে আরও ডেটাটাইপ থাকতে পারে, বা এমনকি তালিকার মধ্যে তালিকাগুলি থাকতে পারে তবে আপনার আরও একটি ব্যাকরণ প্রয়োজন হবে" - দয়া করে আমার উত্তরে প্রদত্ত লিঙ্কটি কোনও পার্সারের জন্য দেখুন যা নেস্টেড তালিকাগুলি এবং অন্যান্য বিভিন্ন ডেটা ধরণের পরিচালনা করবে।
PaulMcG

পাইপার্সিং আর উইকিস্পেসে হোস্ট করা হয় না। parsePythonValue.pyউদাহরণ GitHub থেকে এখন github.com/pyparsing/pyparsing/blob/master/examples/...
PaulMcG

1

জিসসন ব্যবহার করে রায়ের উত্তরটি আরও সম্পূর্ণ করতে ইউনিকোডকে রূপান্তর করতে খুব সুবিধাজনক একটি ফাংশনটি এখানে পোস্ট করা হয়েছে: https://stackoverflow.com/a/13105359/7599285

ডাবল বা একক উদ্ধৃতি সহ প্রাক্তন:

>print byteify(json.loads(u'[ "A","B","C" , " D"]')
>print byteify(json.loads(u"[ 'A','B','C' , ' D']".replace('\'','"')))
['A', 'B', 'C', ' D']
['A', 'B', 'C', ' D']

0

আমি রেগেজ সহ আরও স্বজ্ঞাত প্যাটার্নিং সমাধান সরবরাহ করতে চাই। নীচের ফাংশনটি ইনপুট হিসাবে একটি স্ট্রিংফাইড তালিকা গ্রহণ করে যথেচ্ছ স্ট্রিং রয়েছে।

পদক্ষেপের ব্যাখ্যা: আপনি সমস্ত হোয়াইটস্পেসিং, বন্ধন এবং মান_ স্যাপারেটর সরান (আপনি যে মানগুলিকে উত্তোলন করতে চান সেগুলির অংশ না হলে অন্যথায় রেজেক্স আরও জটিল করে তোলেন)। তারপরে আপনি পরিষ্কার স্ট্রিংটি একক বা ডাবল উদ্ধৃতিতে বিভক্ত করুন এবং খালি শূন্য মানগুলি (বা বিজোড় সূচকযুক্ত মানগুলি, পছন্দ যাই হোক না কেন) নিন।

def parse_strlist(sl):
import re
clean = re.sub("[\[\],\s]","",sl)
splitted = re.split("[\'\"]",clean)
values_only = [s for s in splitted if s != '']
return values_only

পরীক্ষার নমুনা : "['21'," ফু "" 6 ", '0'," এ "]"


0

এবং খাঁটি অজগর সহ - কোনও লাইব্রেরি আমদানি করে না

[x for x in  x.split('[')[1].split(']')[0].split('"')[1:-1] if x not in[',',' , ',', ']]

0

পান্ডাস ডেটা ফ্রেম হিসাবে সঞ্চিত স্ক্র্যাপড ডেটা নিয়ে কাজ করার সময় আপনি এই জাতীয় সমস্যায় পড়তে পারেন।

মানগুলির তালিকা পাঠ্য হিসাবে উপস্থিত থাকলে এই সমাধানটি কবজির মতো কাজ করে ।

def textToList(hashtags):
    return hashtags.strip('[]').replace('\'', '').replace(' ', '').split(',')

hashtags = "[ 'A','B','C' , ' D']"
hashtags = textToList(hashtags)

Output: ['A', 'B', 'C', 'D']

কোন বাহ্যিক গ্রন্থাগার প্রয়োজন।


-1

সুতরাং, সমস্ত উত্তর অনুসরণ করে আমি সবচেয়ে সাধারণ পদ্ধতিগুলির সময় নির্ধারণ করেছি:

from time import time
import re
import json


my_str = str(list(range(19)))
print(my_str)

reps = 100000

start = time()
for i in range(0, reps):
    re.findall("\w+", my_str)
print("Regex method:\t", (time() - start) / reps)

start = time()
for i in range(0, reps):
    json.loads(my_str)
print("json method:\t", (time() - start) / reps)

start = time()
for i in range(0, reps):
    ast.literal_eval(my_str)
print("ast method:\t\t", (time() - start) / reps)

start = time()
for i in range(0, reps):
    [n.strip() for n in my_str]
print("strip method:\t", (time() - start) / reps)



    regex method:    6.391477584838867e-07
    json method:     2.535374164581299e-06
    ast method:      2.4425282478332518e-05
    strip method:    4.983267784118653e-06

শেষ পর্যন্ত রেগেজ জেতা!


-1

আপনি তালিকার স্ট্রিং উপস্থাপনা থেকে প্রথম এবং শেষ অক্ষরগুলি কেবল টুকরো টুকরো করে নিজেকে স্ট্রাস্ট () এফসিএন সংরক্ষণ করতে পারেন (নীচে তৃতীয় লাইনটি দেখুন)

>>> mylist=[1,2,3,4,5,'baloney','alfalfa']
>>> strlist=str(mylist)
['1', ' 2', ' 3', ' 4', ' 5', " 'baloney'", " 'alfalfa'"]
>>> mylistfromstring=(strlist[1:-1].split(', '))
>>> mylistfromstring[3]
'4'
>>> for entry in mylistfromstring:
...     print(entry)
...     type(entry)
... 
1
<class 'str'>
2
<class 'str'>
3
<class 'str'>
4
<class 'str'>
5
<class 'str'>
'baloney'
<class 'str'>
'alfalfa'
<class 'str'>
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.