পাইথনে টুপল বোঝা নেই কেন?


339

যেমনটি আমরা সবাই জানি, তালিকার উপলব্ধি আছে, যেমন

[i for i in [1, 2, 3, 4]]

এবং অভিধানের উপলব্ধি আছে, যেমন

{i:j for i, j in {1: 'a', 2: 'b'}.items()}

কিন্তু

(i for i in (1, 2, 3))

একটি জেনারেটরের মধ্যে শেষ হবে, কোন tupleউপলব্ধি নয়। কেন এমন?

আমার অনুমান যে একটি tupleপরিবর্তনযোগ্য, তবে এটির উত্তর বলে মনে হয় না।


15
একটি সেট বোধগম্যতা রয়েছে - যা দেখতে অনেকটা ডিক বোঝার মতো দেখায় ...
মিগিলসন

3
আপনার {i:j for i,j in {1:'a', 2:'b'}}{i:j for i,j in {1:'a', 2:'b'}.items()}
কোডটিতে

@ ইন্নবররোজ এটিকে দেখানোর জন্য ধন্যবাদ
শ্যাডি জু

কেবল উত্তরসূরির স্বার্থে, পাইথন চ্যাটে
ইনবার রোজ

স্পষ্টতই আছে। stackoverflow.com/a/51811147/9627166
সুপার এস

উত্তর:


470

আপনি একটি জেনারেটর এক্সপ্রেশন ব্যবহার করতে পারেন:

tuple(i for i in (1, 2, 3))

তবে বন্ধনী ইতিমধ্যে… জেনারেটর এক্সপ্রেশন জন্য নেওয়া হয়েছিল।


15
এই যুক্তি দ্বারা, আমরা বলতে পারে একটি তালিকা-ধী খুব অপ্রয়োজনীয়: list(i for i in (1,2,3))। আমি সত্যিই মনে করি এটি কেবল কারণ এটির জন্য একটি পরিষ্কার বাক্য গঠন (বা কমপক্ষে কেউ
একটিও ভাবেননি

79
একটি জেনারেটর এক্সপ্রেশন যা একটি নির্দিষ্ট ধরণের আউটপুট দেয় তা ব্যবহার করার জন্য একটি তালিকা বা সেট বা ডিক বোঝাপড়াটি কেবল সিনট্যাকটিক চিনি। list(i for i in (1, 2, 3))একটি জেনারেটর এক্সপ্রেশন যা একটি তালিকা set(i for i in (1, 2, 3))আউটপুট দেয়, একটি সেট আউটপুট দেয়। তার মানে কি বোঝার বাক্য গঠন প্রয়োজন নেই? সম্ভবত না, তবে এটি অত্যন্ত কার্যকর। বিরল ক্ষেত্রে আপনার পরিবর্তে একটি টিপল প্রয়োজন, জেনারেটর এক্সপ্রেশনটি করবে, স্পষ্ট, এবং অন্য ব্রেস বা বন্ধনী আবিষ্কারের প্রয়োজন নেই।
মার্টিজন পিটারস

16
উত্তরটি স্পষ্টতই কারণ টিপল সিনট্যাক্স এবং প্রথম বন্ধনী অস্পষ্ট
চার্লস সালভিয়া

19
যদি আপনি পারফরম্যান্সের বিষয়ে চিন্তা করেন তবে কোনও বোধগম্যতা এবং কনস্ট্রাক্টর + জেনারেটর ব্যবহারের মধ্যে পার্থক্য সূক্ষ্মের চেয়ে বেশি। কোনও কনস্ট্রাক্টরে পাস করা জেনারেটর ব্যবহারের তুলনায় সমঝোতার ফলে দ্রুত নির্মাণ হয়। পরবর্তী ক্ষেত্রে আপনি পাইথনে ফাংশন তৈরি করে এবং সম্পাদন করছেন এবং ফাংশন ব্যয়বহুল। [thing for thing in things]এর চেয়ে অনেক দ্রুত একটি তালিকা তৈরি করে list(thing for thing in things)। একটি tuple বোঝাপড়া অকেজো হবে না; tuple(thing for thing in things)বিলম্বিত সমস্যা রয়েছে এবং tuple([thing for thing in things])মেমরির সমস্যা থাকতে পারে।
জাস্টিন টার্নার আর্থার

9
@ মার্তিজজনপিটারস, আপনি কি সম্ভাব্যভাবে উচ্চারণ করতে পারেন A list or set or dict comprehension is just syntactic sugar to use a generator expression? এটা যার ফলে এর বিভ্রান্তির এই এইজন্য মানুষ সমতুল্য শেষ মানে। এটি প্রযুক্তিগতভাবে সিনট্যাকটিক চিনি নয় কারণ শেষের পণ্যটি একই রকম হলেও প্রক্রিয়াগুলি পৃথক।
জেপিপি

77

রেমন্ড হেইটিঙ্গার (পাইথন কোর বিকাশকারীদের মধ্যে একটি) এর সাম্প্রতিক একটি টুইটের মধ্যে টিপলস সম্পর্কে এটি বলেছিলেন :

# পাইথন টিপ: সাধারণত, তালিকাগুলি লুপিংয়ের জন্য হয়; স্ট্রাক্ট জন্য tuples। তালিকাগুলি একজাতীয়; ভিন্ন ভিন্নজাতীয়। পরিবর্তনশীল দৈর্ঘ্যের জন্য তালিকা।

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

struct {
    int a;
    char b;
    float c;
} foo;

struct foo x = { 3, 'g', 5.9 };

পাইথনে পরিণত হয়

x = (3, 'g', 5.9)

26
অপরিবর্তনযোগ্যতা সম্পত্তি গুরুত্বপূর্ণ হতে পারে এবং প্রায়শই আপনি সাধারণত একটি তালিকা ব্যবহার করবেন যখন একটি টিউপল ব্যবহার করার একটি ভাল কারণ। উদাহরণস্বরূপ, যদি আপনার 5 টি সংখ্যার একটি তালিকা থাকে যা আপনি ডিকের কী হিসাবে ব্যবহার করতে চান তবে টুপল হ'ল উপায়।
প্যাভন

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

2
@ ডেভ আপনি সম্ভবত সেক্ষেত্রে কেবল ব্যবহার করতে পারেন operator.itemgetter
চিপনার

@ চেপার, আমি দেখছি এটি আমার অর্থের খুব কাছাকাছি। এটি একটি কলযোগ্য ফিরিয়ে দেয় তাই যদি আমি কেবল এটি করা দরকার তবে আমি tuple(obj[item] for item in items)সরাসরি সরাসরি ব্যবহার করে কোন জয়ের বেশি দেখতে পাচ্ছি না । আমার ক্ষেত্রে আমি টিপল রেকর্ডগুলির একটি তালিকা তৈরি করতে একটি তালিকা বোধের মধ্যে এটি এম্বেড করছি। যদি পুরো কোড জুড়ে আমাকে বারবার এটি করার দরকার হয় তবে আইটেমজিটারটি দুর্দান্ত দেখাচ্ছে। সম্ভবত আইটেমটারটি কোনওভাবেই আরও মূর্খ হবে?
ডেভ

আমি হিমশীতল এবং টিউপল এবং তালিকার সাথে সাদৃশ্য সেট মধ্যে সম্পর্ক দেখতে। এটি বৈচিত্র্য সম্পর্কে কম এবং অপরিবর্তনযোগ্যতা সম্পর্কে আরও বেশি - হিমায়িত এবং টিপলগুলি অভিধান, তালিকা এবং সেটগুলির কী হতে পারে তাদের পরিবর্তনের কারণে নয়।
বহুগ্লোট

56

পাইথন ৩.৩ *থেকে আপনি জেনারেটরের এক্সপ্রেসন আনপ্যাক করতে স্প্লট আনপ্যাকিং সিনট্যাক্সও ব্যবহার করতে পারেন :

*(x for x in range(10)),

2
এটি দুর্দান্ত (এবং এটি কাজ করে) তবে এটি নথিবদ্ধ কোথাও খুঁজে পাচ্ছি না! আপনার কি লিংক আছে?
ফেলিক্সফেজ

8
দ্রষ্টব্য: বাস্তবায়নের বিশদ হিসাবে, এটি মূলত করণের মতোই tuple(list(x for x in range(10)))( কোড পাথগুলি অভিন্ন , উভয়ই একটি নির্মাণের listসাথে একমাত্র পার্থক্য যে চূড়ান্ত পদক্ষেপটি একটি tupleথেকে তৈরি করা listএবং listযখন tupleআউটপুট ফেলে দেয় তখন ফেলে দেওয়া হয়) দরকার). এর অর্থ হল যে আপনি আসলে একজোড়া টেম্পোরারি এড়িয়ে চলবেন না।
শ্যাডোর্যাঞ্জার

4
@ শ্যাডোএ্যাঞ্জার এর মন্তব্যে প্রসারিত করার জন্য, এখানে একটি প্রশ্ন রয়েছে যেখানে তারা দেখায় যে স্প্লট + টিপল আক্ষরিক বাক্য গঠন টিউপল কনস্ট্রাক্টরের কাছে জেনারেটর এক্সপ্রেশনটি পাস করার চেয়ে কিছুটা ধীর।
লুকুবরেটর

আমি পাইথন ৩.7.৩ এ চেষ্টা করছি এবং *(x for x in range(10))কাজ করে না। আমি পেতে SyntaxError: can't use starred expression here। তবে tuple(x for x in range(10))কাজ করে।
রায়ান এইচ।

4
@RyanH। আপনার শেষ দিকে কমা রাখা দরকার।
czheo

27

অন্য পোস্টার হিসাবে macmউল্লেখ করা হয়েছে, জেনারেটর থেকে টিপল তৈরির দ্রুততম উপায় হ'ল tuple([generator])


পারফরম্যান্স তুলনা

  • তালিকা উপলব্ধি:

    $ python3 -m timeit "a = [i for i in range(1000)]"
    10000 loops, best of 3: 27.4 usec per loop
  • তালিকা অনুধাবন থেকে দ্বিগুণ:

    $ python3 -m timeit "a = tuple([i for i in range(1000)])"
    10000 loops, best of 3: 30.2 usec per loop
  • জেনারেটর থেকে টিপল:

    $ python3 -m timeit "a = tuple(i for i in range(1000))"
    10000 loops, best of 3: 50.4 usec per loop
  • আনপ্যাকিং থেকে টিপল:

    $ python3 -m timeit "a = *(i for i in range(1000)),"
    10000 loops, best of 3: 52.7 usec per loop

অজগরটির আমার সংস্করণ :

$ python3 --version
Python 3.6.3

সুতরাং কর্মক্ষমতা কোনও সমস্যা না হলে তালিকার বোধ থেকে আপনার সর্বদা একটি টিপল তৈরি করা উচিত।


10
দ্রষ্টব্য: tupleএর listcomp একটি শিখর মেমরির চূড়ান্ত যৌথ আকারের উপর ভিত্তি করে ব্যবহার করা প্রয়োজন tupleএবং listtupleএকটি জিনেক্সেরপ্রের, ধীরে ধীরে, এর অর্থ হ'ল আপনি কেবল চূড়ান্ত জন্য অর্থ প্রদান করেন tuple, কোনও অস্থায়ী নয় list(জেনেক্সপ্রি নিজেই প্রায় স্থির স্মৃতি ধারণ করে)। সাধারণত অর্থবহ নয়, তবে জড়িত আকারগুলি বিশাল হলে এটি গুরুত্বপূর্ণ হতে পারে।
শ্যাডোর্যাঞ্জার

25

সমঝোতা আইটেমগুলি লুপিং বা পুনরাবৃত্তি করে এবং সেগুলি একটি ধারক হিসাবে বরাদ্দ করে কাজ করে, একটি টুপল অ্যাসাইনমেন্টগুলি গ্রহণ করতে অক্ষম।

একবার একটি টিউপল তৈরি হয়ে গেলে, এটি সংযোজন, প্রসারিত বা নির্ধারিত হতে পারে না। টুপলকে সংশোধন করার একমাত্র উপায় হ'ল যদি এর কোনও একটি বস্তু নিজেই বরাদ্দ করা যায় (এটি একটি নন-টুপল ধারক)। কারণ টিপল কেবল kind ধরণের অবজেক্টের একটি রেফারেন্স ধারণ করে।

এছাড়াও - একটি টুপলের নিজস্ব কনস্ট্রাক্টর রয়েছে tuple()যা আপনি যে কোনও পুনরুক্তি দিতে পারেন। যার অর্থ হল একটি টিপল তৈরি করতে, আপনি এটি করতে পারেন:

tuple(i for i in (1,2,3))

9
কিছু উপায়ে আমি সম্মত (এটি প্রয়োজনীয় নয় কারণ একটি তালিকা করবে), তবে অন্য উপায়ে আমি একমত নই (যুক্তিটি কারণ এটি অপরিবর্তনীয়) সম্পর্কে। কিছু উপায়ে, অপরিবর্তনীয় বস্তুর বোঝার জন্য এটি আরও বোধগম্য হয়। কে করে lst = [x for x in ...]; x.append()?
মিগিলসন

@ এমগিলসন আমি নিশ্চিত নই যে আমি যা বলেছিলাম তার সাথে এটি কীভাবে সম্পর্কিত?
ইনবার রোজ

2
@ মিগিলসন যদি একটি টুপল অবিচ্ছেদ্য হয় তার মানে অন্তর্নিহিত বাস্তবায়ন একটি টিপলকে "জেনারেট" করতে পারে না ("প্রজন্ম" একবারে এক টুকরো বিল্ডিং বোঝায়)। অপরিবর্তনীয় মানে আপনি 3 টি টুকরা দিয়ে একটি পরিবর্তন করে 4 টি টুকরা দিয়ে এটি তৈরি করতে পারবেন না। পরিবর্তে, আপনি একটি তালিকা তৈরির মাধ্যমে টুপল "প্রজন্ম" প্রয়োগ করেন, প্রজন্মের জন্য ডিজাইন করা কিছু, তারপরে শেষ পদক্ষেপ হিসাবে টিপলটি তৈরি করুন এবং তালিকাটি বাতিল করুন। ভাষা এই বাস্তবতা প্রতিফলিত করে। টি স্টলসকে সি স্ট্রাক্ট হিসাবে ভাবেন।
স্কট

2
যদিও বোধগম্য সিনট্যাকটিক চিনির জন্য টিপলসের জন্য কাজ করা যুক্তিসঙ্গত হবে, যেহেতু আপনি বোঝা ফিরে না আসা পর্যন্ত আপনি টিপলটি ব্যবহার করতে পারবেন না। কার্যকরভাবে এটি মিউটেবলের মতো কাজ করে না, বরং একটি দ্বৈত বোধগম্যতা স্ট্রিং সংযোজনের মতো আচরণ করতে পারে।
উছুগাকা

12

আমার সর্বোত্তম অনুমান যে তারা বন্ধনীর বাইরে চলে গেছে এবং তারা "কুৎসিত" সিনট্যাক্স যুক্ত করে ওয়ারেন্টের পক্ষে যথেষ্ট কার্যকর হবে বলে মনে করেনি ...


1
অ্যাঙ্গেল বন্ধনীগুলি অব্যবহৃত।
উছুগাকা

@ কুচুগাকা - পুরোপুরি নয়। এগুলি তুলনা অপারেটরগুলির জন্য ব্যবহৃত হয়। এটি সম্ভবত অস্পষ্টতা ছাড়াই করা যেতে পারে, তবে সম্ভবত প্রচেষ্টাটির পক্ষে মূল্যবান নয় ...
মিগিলসন

3
@ মুচুগাকা মূল্যবান যে {*()}, কুৎসিত হলেও খালি সেট আক্ষরিক হিসাবে কাজ করে!
এমআই রাইট

1
বিতৃষ্ণা। একটি নান্দনিক দৃষ্টিকোণ থেকে, আমি মনে করি যে আমি আংশিক আছি set():)
মিগিলসন

1
@ কোয়ান্টামমেকানিক: হ্যাঁ, এটাই মূল বিষয়; আনপ্যাকিংয়ের সাধারণীকরণগুলি খালি "সেটকে আক্ষরিক" সম্ভব করেছে। নোটটি যে {*[]}অন্য বিকল্পগুলির চেয়ে কঠোরভাবে নিকৃষ্টতর; খালি স্ট্রিং এবং খালি tuple, অপরিবর্তনীয় হ'ল সিঙ্গেলন, তাই খালিটি তৈরি করার জন্য কোনও অস্থায়ী প্রয়োজন হয় না set। বিপরীতে, listখালিটি একটি সিঙ্গলটন নয়, সুতরাং আপনাকে এটি নির্মাণ করতে হবে, এটি তৈরির জন্য এটি ব্যবহার করতে হবে set, তারপরে এটি ধ্বংস করতে হবে, একু চোখের বানর অপারেটর যে পরিমাণ তুচ্ছ কর্মক্ষমতা সুবিধা দেয় তা হারাতে হবে।
শ্যাডোর্যাঞ্জার

8

টিপলগুলি দক্ষতার সাথে তালিকার মতো যুক্ত করা যায় না।

সুতরাং একটি দ্বিগুণ বোঝার জন্য অভ্যন্তরীণভাবে একটি তালিকা ব্যবহার করা এবং তারপরে একটি টিউপলে রূপান্তর করা প্রয়োজন।

আপনি এখন যা করেন তা হ'ল: টিপল ([বোঝা])


3

প্যারেন্টিসিস একটি টুপল তৈরি করে না। ওরফে ওয়ান = (দুই) টিপল নয়। চারপাশের একমাত্র উপায় হ'ল হয় এক = (দুই,) বা এক = টিপল (দুটি)। সুতরাং একটি সমাধান হল:

tuple(i for i in myothertupleorlistordict) 

সুন্দর। এটা প্রায় একই।
উছুগাকা

-1

আমি বিশ্বাস করি যে এটি কেবল স্বচ্ছতার জন্য, আমরা ভাষাটি খুব বেশি আলাদা চিহ্ন সহ বিশৃঙ্খলা করতে চাই না। এছাড়াও কোনও tupleবোঝাপড়া কখনই প্রয়োজন হয় না , তালিকার বোধগমির বিপরীতে ডিক বোঝার বিপরীতে একটি তালিকা কেবল नगনীয় গতির পার্থক্যগুলির সাথে ব্যবহার করা যেতে পারে।


-2

আমরা একটি তালিকা বোধগম্য থেকে টিপলস তৈরি করতে পারি। নিম্নলিখিতটি একটি টিপলে ক্রমান্বয়ে দুটি সংখ্যা যুক্ত করে এবং 0-9 নম্বর থেকে একটি তালিকা দেয়।

>>> print k
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> r= [tuple(k[i:i+2]) for i in xrange(10) if not i%2]
>>> print r
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.