(X x== এবং y == খ) বা (x == বি এবং y == ক) প্রকাশ করার জন্য আরও কি মার্জিত উপায় আছে?


108

আমি ((x == a and y == b) or (x == b and y == a))পাইথনে মূল্যায়ন করার চেষ্টা করছি তবে এটি কিছুটা ভারবস বলে মনে হচ্ছে। আরও কি মার্জিত উপায় আছে?


8
কী ধরণের অবজেক্টগুলি নির্ভর করে x,y, a,b: এগুলি কি ইনটস / ফ্লোট / স্ট্রিং, স্বেচ্ছাসেবী বস্তু বা কী? যদি সেগুলি অন্তর্নির্মিত ধরণের ছিল x,yএবং উভয় এবং সজ্জিতভাবে রাখা সম্ভব ছিল a,b, তবে আপনি দ্বিতীয় শাখাটি এড়াতে পারবেন। নোট করুন যে একটি সেট তৈরি করার ফলে চারটি উপাদানগুলির প্রত্যেককেই x,y, a,bধাবিত হবে, যা তুচ্ছ বা নাও হতে পারে বা তারা কী ধরণের বস্তুগুলির উপর নির্ভর করে কোনও পারফরম্যান্সের সাথে জড়িত থাকতে পারে।
smci

18
আপনি যাদের সাথে কাজ করেন এবং যে ধরণের প্রকল্প আপনি বিকাশ করছেন তা মনে রাখবেন। আমি এখানে এবং সেখানে একটু পাইথন ব্যবহার করি। যদি কেউ এখানে একটি উত্তর কোড করে থাকে তবে আমাকে সম্পূর্ণরূপে গুগল করতে হবে কি হচ্ছে। আপনার শর্তসাপেক্ষে যাই হোক না কেন বেশ পাঠযোগ্য।
Areks

3
আমি কোনও প্রতিস্থাপন নিয়ে বিরক্ত করব না। এগুলি আরও পরিশ্রুত, তবে পরিষ্কার নয় (আইএমএইচও) এবং আমি মনে করি সব ধীরে ধীরে হবে।
বার্মার

22
এটি ক্লাসিক এক্সওয়াইবি সমস্যা problem
তাশুস

5
এবং সাধারণভাবে যদি আপনি অবজেক্টগুলির অর্ডার-স্বতন্ত্র সংগ্রহের সাথে কাজ করছেন, সেট / ডিক্টস / ইত্যাদি ব্যবহার করুন। এটি সত্যই একটি এক্সওয়াই সমস্যা, এটির থেকে বৃহত্তর কোডবেসটি আমাদের দেখার দরকার। আমি সম্মত হই যে ((x == a and y == b) or (x == b and y == a)), যুকি দেখতে পাবে, তবে 1) এর উদ্দেশ্যটি ক্রিস্টাল নয়, সমস্ত অ পাইথন প্রোগ্রামারদের কাছে স্ফটিক স্বচ্ছ এবং স্বচ্ছ বিকল্প। সুতরাং, 'আরও মার্জিত' এর মারাত্মক ডাউনসাইডও হতে পারে।
smci

উত্তর:


151

যদি উপাদানগুলি হ্যাশযোগ্য হয় তবে আপনি সেটগুলি ব্যবহার করতে পারেন:

{a, b} == {y, x}

18
@ গ্রাহাম না এটি হয় না, কারণ ডান হাতের সেটটিতে ঠিক দুটি আইটেম রয়েছে। যদি উভয়ই এক হয়, খ নেই, এবং উভয়ই খ হয়, একটি নেই, এবং উভয় ক্ষেত্রেই সেটগুলি সমান হতে পারে না।
hobbs

12
অন্যদিকে, যদি প্রতিটি দিকে আমাদের তিনটি উপাদান থাকে এবং সেগুলি একে অপরের সাথে মিলে যায় কিনা তা আমাদের পরীক্ষা করা দরকার, তবে সেটগুলি কাজ করবে না। {1, 1, 2} == {1, 2, 2}। এই মুহুর্তে, আপনার প্রয়োজন sortedবা Counter
ব্যবহারকারী 2357112 মনিকা

11
আমি পড়ার পক্ষে এই কৌশলটি খুঁজে পেয়েছি ("{}" হিসাবে "()" পড়বেন না)। এটি মন্তব্য করার জন্য যথেষ্ট - এবং তারপরে উদ্দেশ্যটি হারিয়ে যায়।
Edouard

9
আমি জানি এটি অজগর তবে মানগুলির তুলনা করার জন্য দুটি নতুন সেট তৈরি করা আমার কাছে একটি ওভারকিলের মতো বলে মনে হচ্ছে ... কেবল একটি ফাংশন সংজ্ঞায়িত করুন যা এটি করে এবং যখন প্রয়োজন হয় তখন কল করে।
মার্কসিন

5
@ মার্কসিন একটি ফাংশন 2 টি সহজ সেট নির্মাণের চেয়ে আরও বেশি ওভারকিল হবে। এবং 4 টি যুক্তি সহ কম পাঠযোগ্য।
গ্লোয়ে

60

আমি মনে করি আপনি যে সেরাটি পেতে পারেন তা হ'ল এগুলিকে টিপলসে প্যাকেজ করা:

if (a, b) == (x, y) or (a, b) == (y, x)

বা, সম্ভবত সেট সেট মধ্যে এটি মোড়ানো

if (a, b) in {(x, y), (y, x)}

এটি যেহেতু কয়েকটি মন্তব্য দ্বারা উল্লেখ করা হয়েছিল, তাই আমি কিছু সময় করেছিলাম এবং লুপ ব্যর্থ হওয়ার সাথে সাথে এখানে টিপলস এবং সেটগুলি একইভাবে সম্পাদন করতে দেখা যায়:

from timeit import timeit

x = 1
y = 2
a = 3
b = 4

>>> timeit(lambda: (a, b) in {(x, y), (y, x)}, number=int(5e7))
32.8357742

>>> timeit(lambda: (a, b) in ((x, y), (y, x)), number=int(5e7))
31.6169182

যদিও চেহারা সফল হয় যখন টিপলগুলি আসলে দ্রুত হয়:

x = 1
y = 2
a = 1
b = 2

>>> timeit(lambda: (a, b) in {(x, y), (y, x)}, number=int(5e7))
35.6219458

>>> timeit(lambda: (a, b) in ((x, y), (y, x)), number=int(5e7))
27.753138700000008

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


12
টিপল পদ্ধতিটি খুব পরিষ্কার দেখাচ্ছে। আমি একটি সেট ব্যবহারের পারফরম্যান্স প্রভাব সম্পর্কে উদ্বিগ্ন থাকব। আপনি করতে পারেন if (a, b) in ((x, y), (y, x)), যদিও?
ব্রিলিয়ানড

18
@ ব্রিলিয়ানড যদি আপনি পারফরম্যান্স প্রভাব সম্পর্কে উদ্বিগ্ন হন তবে পাইথন আপনার পক্ষে ভাষা নয়। :-D
স্নেফটেল

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

set@ ব্রিলিয়ান্ডের টিউপল সমাধানের উত্তরে সমাধানটি পছন্দ করার কোনও কারণ আছে কি ?
ব্যবহারকারী 1717828

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

31

টিপলস এটিকে কিছুটা বেশি পঠনযোগ্য করে তোলে:

(x, y) == (a, b) or (x, y) == (b, a)

এটি একটি সূত্র দেয়: আমরা ক্রমটি ক্রমের x, yসমান বা ক্রমানুসারে a, bঅগ্রাহ্য করে যাচাই করছি । এটাই সবেমাত্র সমতা!

{x, y} == {a, b}

,একটি তালিকা তৈরি করে, একটি তালিকা তৈরি করে না। সুতরাং (x, y)এবং (a, b)tuples হয়, x, yএবং হিসাবে একই a, b
কিসিজিরি

আমি পাইথনের listধরণের অর্থে নয়, "উপাদানের ক্রমযুক্ত ক্রম" অর্থে "তালিকা" বলতে চাইছিলাম । সম্পাদিত কারণ সত্যই এটি বিভ্রান্তিকর ছিল।
টমাস

27

যদি আইটেমগুলি হ্যাশযোগ্য না হয় তবে তুলনা করার আদেশকে সমর্থন করে তবে আপনি চেষ্টা করতে পারেন:

sorted((x, y)) == sorted((a, b))

যেহেতু এটি হ্যাশযোগ্য আইটেমগুলির সাথেও কাজ করে (ডান?), এটি আরও বিশ্বব্যাপী সমাধান।
কার্ল উইথফট

5
@ কার্লউইথথফট: না There এমন কিছু প্রকার রয়েছে যা হ্যাশযোগ্য তবে বাছাইযোগ্য নয়: complexউদাহরণস্বরূপ।
dan04

26

আমার মতে সর্বাধিক মার্জিত উপায় হবে

(x, y) in ((a, b), (b, a))

এটি সেটগুলি ব্যবহার করার চেয়ে ভাল উপায়, যেমন {a, b} == {y, x}, অন্যান্য উত্তরে উল্লিখিত রয়েছে কারণ ভেরিয়েবলগুলি ধাবনযোগ্য কিনা তা আমাদের ভাবার দরকার নেই।


এটি পূর্বের উত্তর থেকে কীভাবে আলাদা ?
scohe001

5
@ scohe001 এটি এমন একটি টুপল ব্যবহার করে যেখানে পূর্বের উত্তরগুলি সেট ব্যবহার করে। পূর্ববর্তী উত্তরগুলি এই সমাধানটিকে বিবেচনা করেছিল, তবে এটি একটি প্রস্তাব হিসাবে তালিকাভুক্ত করতে অস্বীকার করেছিল।
ব্রিলিয়ানড

25

এগুলি যদি সংখ্যা হয় তবে আপনি ব্যবহার করতে পারেন (x+y)==(a+b) and (x*y)==(a*b)

যদি এগুলি তুলনামূলক আইটেম হয় তবে আপনি ব্যবহার করতে পারেন min(x,y)==min(a,b) and max(x,y)==max(a,b)

তবে ((x == a and y == b) or (x == b and y == a))এটি পরিষ্কার, নিরাপদ এবং আরও সাধারণ।


2
হাহা, প্রতিসম বহুবর্ষ এফটিডব্লিউ!
কার্স্টেন এস

2
আমি মনে করি এটি ওভারফ্লো ত্রুটির ঝুঁকি তৈরি করে।
রাজ্জওয়ান সোসোল

3
এটি সঠিক উত্তর, বিশেষত শেষ বাক্য। এটি সহজ রাখুন, এর জন্য একাধিক নতুন পুনরাবৃত্ত বা এমন কিছু প্রয়োজন হবে না। যারা সেট ব্যবহার করতে চান তাদের জন্য সেট অবজেক্টগুলির বাস্তবায়নটি একবার দেখুন এবং তারপরে একটি
টান

3
@ রাজ্জানসোকল ওপি ডেটা প্রকারগুলি কী তা বলেনি এবং এই উত্তরটি টাইপ-নির্ভর নির্ভর সমাধানগুলি যোগ্য করে তোলে।
জেড 4-স্তর

21

আমরা দুটিরও বেশি ভেরিয়েবলের সাধারণীকরণ হিসাবে ব্যবহার করতে পারি itertools.permutations। পরিবর্তে হয়

(x == a and y == b and z == c) or (x == a and y == c and z == b) or ...

আমরা লিখতে পারি

(x, y, z) in itertools.permutations([a, b, c])

এবং অবশ্যই দুটি পরিবর্তনশীল সংস্করণ:

(x, y) in itertools.permutations([a, b])

5
দুর্দান্ত উত্তর। এখানে এটি উল্লেখ করা মূল্যবান (যারা জেনারেটরগুলির সাথে এর আগে খুব বেশি কিছু করেন নি) তাদের পক্ষে এটি অত্যন্ত স্মৃতিশক্তি দক্ষ, কারণ একসাথে কেবলমাত্র একটির অনুক্রম তৈরি করা হয়েছিল, এবং "ইন" চেকটি থামবে এবং অবিলম্বে সত্যটি ফিরে আসবে মিল পাওয়া যায়।
রবার্টলেটন

2
এই পদ্ধতির জটিলতা এটিও উল্লেখ করার মতো O(N*N!); ১১ টি ভেরিয়েবলের জন্য, এটি শেষ হতে এক সেকেন্ড সময় নিতে পারে। (আমি একটি দ্রুত পদ্ধতি পোস্ট করেছি, তবে এটি এখনও গ্রহণ করে O(N^2)এবং 10 কে ভেরিয়েবলগুলিতে এক সেকেন্ড গ্রহণ করতে শুরু করে; সুতরাং মনে হয় এটি দ্রুত বা সাধারণভাবে করা যেতে পারে) (উভয়ভাবেই নয়) / পি) উভয়ই নয়: পি)
আলেক্সি তোড়হামো

15

আপনি আপনার ডেটা উপস্থাপন করতে টিপলস ব্যবহার করতে পারেন এবং তারপরে সেট অন্তর্ভুক্তির জন্য পরীক্ষা করতে পারেন:

def test_fun(x, y):
    test_set = {(a, b), (b, a)}

    return (x, y) in test_set

3
ওয়ান-লাইনার হিসাবে এবং একটি তালিকা সহ (নন-হ্যাশযোগ্য আইটেমগুলির জন্য) লেখা, আমি এটিকে সেরা উত্তর হিসাবে বিবেচনা করব। (যদিও আমি সম্পূর্ণ পাইথন নবাগত))
Edouard

1
@ অ্যাডওয়ার্ড এখন আরও একটি উত্তর রয়েছে যা মূলত এটি (কেবলমাত্র তালিকার পরিবর্তে একটি টিপল দিয়ে, যা যাইহোক আরও কার্যকর।
ব্রিলিয়ানড

10

আপনি ইতিমধ্যে সর্বাধিক পঠনযোগ্য সমাধান পেয়েছেন । এটি প্রকাশের অন্যান্য উপায় রয়েছে, সম্ভবত কম অক্ষর রয়েছে তবে তারা পড়তে কম সোজা-এগিয়ে রয়েছে।

মানগুলি আপনার সেরা বাজিকে কী উপস্থাপন করে তার উপর নির্ভর করে কোনও স্পিচিং নাম দিয়ে কোনও ফাংশনে চেকটি মোড়ানো । বিকল্প বা অতিরিক্ত হিসাবে, আপনি নিখুঁত উচ্চ শ্রেণীর বস্তুগুলিতে প্রতিটি x, y এবং a, b অবজেক্টগুলিকে মডেল করতে পারেন যা আপনি ক্লাসের সাম্যতা পরীক্ষা পদ্ধতিতে বা উত্সর্গীকৃত কাস্টম ফাংশনে তুলনার যুক্তির সাথে তুলনা করতে পারেন।


3

দেখে মনে হচ্ছে ওপি কেবল দুটি ভেরিয়েবলের ক্ষেত্রেই উদ্বিগ্ন ছিল, তবে স্ট্যাকওভারফ্লো যেহেতু পরে একই প্রশ্নটি অনুসন্ধান করে তাদের জন্যও, আমি এখানে জেনেরিক কেসটি কিছুটা বিশদভাবে সমাধান করার চেষ্টা করব; এক পূর্ববর্তী উত্তর ইতিমধ্যে একটি জেনেরিক উত্তর ব্যবহার রয়েছে itertools.permutations(), কিন্তু যে পদ্ধতি বিশালাকার O(N*N!)তুলনা, যেহেতু আছে N!সঙ্গে একাধিক বিন্যাসন Nআইটেম প্রতিটি। (এটি এই উত্তরের মূল প্রেরণা ছিল)

প্রথমে সংক্ষেপে বলা যাক পূর্ববর্তী উত্তরের কয়েকটি পদ্ধতি জেনেরিক ক্ষেত্রে কীভাবে প্রয়োগ করা হয়, এখানে উপস্থাপিত পদ্ধতির অনুপ্রেরণা হিসাবে। আমি ব্যবহার করছি Aউল্লেখ করতে (x, y)এবং Bউল্লেখ করতে (a, b), নির্বিচারে (কিন্তু সমান) দৈর্ঘ্যের tuples হতে পারে।

set(A) == set(B)দ্রুত, তবে কেবল তখনই কাজ করে যদি মানগুলি হ্যাশযোগ্য হয় এবং আপনি গ্যারান্টি দিতে পারবেন যে কোনও একটি টিপলে কোনও নকল মান নেই। (উদাহরণস্বরূপ {1, 1, 2} == {1, 2, 2}, @ ড্যানিয়েল মেসেজোর জবাবের নীচে @ ব্যবহারকারী 2357112 দ্বারা নির্দেশিত হিসাবে)

পূর্ববর্তী পদ্ধতিটি সেটগুলির পরিবর্তে গণনা সহ অভিধান ব্যবহার করে সদৃশ মানগুলির সাথে কাজ করার জন্য প্রসারিত হতে পারে: (এটি এখনও সীমাবদ্ধতা রয়েছে যে সমস্ত মানগুলি হ্যাশেবল হওয়া দরকার, যেমন, যেমন: পরিবর্তনীয় মানগুলি যেমন listকাজ করবে না)

def counts(items):
    d = {}
    for item in items:
        d[item] = d.get(item, 0) + 1
    return d

counts(A) == counts(B)

sorted(A) == sorted(B)হ্যাশেবল মানগুলির প্রয়োজন হয় না, তবে এটি কিছুটা ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে উন্নত হয়। (সুতরাং যেমন। complexকাজ করবে না)

A in itertools.permutations(B)হ্যাশেবল বা অরিডেবল মানগুলির প্রয়োজন হয় না, তবে ইতিমধ্যে উল্লিখিত মতো এর O(N*N!)জটিলতা রয়েছে, তাই মাত্র ১১ টি আইটেমের সাথেও এটি শেষ হতে এক সেকেন্ড সময় নিতে পারে।

সুতরাং, সাধারণ হওয়ার মতো কোনও উপায় আছে তবে এটি কি যথেষ্ট দ্রুত হয়? হ্যাঁ, "ম্যানুয়ালি" যাচাই করে প্রতিটি আইটেমের সমান পরিমাণ রয়েছে: (এটির জটিলতা হ'ল O(N^2)এটি বড় ইনপুটগুলির পক্ষেও ভাল নয়; আমার মেশিনে 10 কে আইটেম একটি সেকেন্ডও নিতে পারে - তবে সাথে 10 টি আইটেমের মতো ছোট ইনপুটগুলি এটি অন্যদের মতোই দ্রুত)

def unordered_eq(A, B):
    for a in A:
        if A.count(a) != B.count(a):
            return False
    return True

সেরা পারফরম্যান্স পেতে, কেউ dictপ্রথমে sortedবেসড পদ্ধতিটি চেষ্টা করে দেখতে পারেন, যদি অসাধ্যযোগ্য মানগুলির কারণে ব্যর্থ হয় তবে বেসড countপদ্ধতিতে ফিরে যান এবং অবশেষে যদি বেসড পদ্ধতিতে ব্যর্থ হয় তবে বেসড পদ্ধতিতে ফিরে যান ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.