তালিকা বোঝাপড়া: প্রতিটি আইটেমের জন্য দুটি (বা আরও) আইটেম ফিরিয়ে দেওয়া


92

একটি তালিকা বোঝার মধ্যে প্রতিটি আইটেমের জন্য 2 (বা আরও) আইটেম ফেরত দেওয়া সম্ভব?

আমি যা চাই (উদাহরণ):

[f(x), g(x) for x in range(n)]

ফিরে আসা উচিত [f(0), g(0), f(1), g(1), ..., f(n-1), g(n-1)]

সুতরাং, কোডের এই ব্লকটি প্রতিস্থাপন করার জন্য কিছু:

result = list()
for x in range(n):
    result.add(f(x))
    result.add(g(x))

4
কৌতূহলের বাইরে আপনি কেন এটি করতে চান? এভাবে শেষ না করে নিজের শেষ লক্ষ্য অর্জনের আরও ভাল উপায় হতে পারে।
murgatroid99

4
মূলত কারণ আমি ফাংশনাল প্রোগ্রামিং পছন্দ করি। আমি পাইগলেট.গ্রাফিক্স.ড্র ফাংশনের সাথে ব্যবহার করতে স্ক্রিনের স্থানাঙ্কগুলির একটি বেশিরভাগ স্থানাঙ্কের একটি তালিকা মানচিত্র করতে চাই।
হাশমুশ 8'12

উত্তর:


54
>>> from itertools import chain
>>> f = lambda x: x + 2
>>> g = lambda x: x ** 2
>>> list(chain.from_iterable((f(x), g(x)) for x in range(3)))
[2, 0, 3, 1, 4, 4]

সময়:

from timeit import timeit

f = lambda x: x + 2
g = lambda x: x ** 2

def fg(x):
    yield f(x)
    yield g(x)

print timeit(stmt='list(chain.from_iterable((f(x), g(x)) for x in range(3)))',
             setup='gc.enable(); from itertools import chain; f = lambda x: x + 2; g = lambda x: x ** 2')

print timeit(stmt='list(chain.from_iterable(fg(x) for x in range(3)))',
             setup='gc.enable(); from itertools import chain; from __main__ import fg; f = lambda x: x + 2; g = lambda x: x ** 2')

print timeit(stmt='[func(x) for x in range(3) for func in (f, g)]',
             setup='gc.enable(); f = lambda x: x + 2; g = lambda x: x ** 2')


print timeit(stmt='list(chain.from_iterable((f(x), g(x)) for x in xrange(10**6)))',
             setup='gc.enable(); from itertools import chain; f = lambda x: x + 2; g = lambda x: x ** 2',
             number=20)

print timeit(stmt='list(chain.from_iterable(fg(x) for x in xrange(10**6)))',
             setup='gc.enable(); from itertools import chain; from __main__ import fg; f = lambda x: x + 2; g = lambda x: x ** 2',
             number=20)

print timeit(stmt='[func(x) for x in xrange(10**6) for func in (f, g)]',
             setup='gc.enable(); f = lambda x: x + 2; g = lambda x: x ** 2',
             number=20)

2.69210777094

3.13900787874

1.62461071932

25.5944058287

29.2623711793

25.7211849286


4
এই কোড অপ্রয়োজনীয় tuples তৈরি করে (f(x), g(x))। ভাল হিসেবে লেখা যেতে যায়নি: def fg(x): yield x + 2; yield x ** 2; list(chain.from_iterable(fg(x) for x in range(3)))
খচিক

4
আপনি এটি দিয়ে সাধারণীকরণও করতে পারেন chain.from_iterable((func(x) for func in funcs) for x in range(n)))। যা ঘটনাক্রমে খচিকের অভিযোগ দূর করবে। (যদিও একটি অর্থে আমার ও তাঁর মূলত প্রক্রিয়া পরিপ্রেক্ষিতে একই আমরা কেবল ভেতরের জেনারেটরের ভিন্নভাবে সংজ্ঞায়িত করুন।।)
Jab

এটি আমার sum(..., [])উত্তরের চেয়ে ভাল কারণ এর জন্য প্রতিটি + (এইভাবে ও (এন ^ 2) পারফরম্যান্সের চেয়ে ও (এন) পারফরম্যান্সের তালিকা পুনরুদ্ধার প্রয়োজন হয় না)। আমি sum(..., [])যখন দ্রুত ওয়ান-লাইনার চাইব বা আমি তাড়াহুড়ো করতে চাইছি বা শব্দের সংখ্যার সীমাবদ্ধ করা হবে তখনও আমি ব্যবহার করব (যেমন <= 10)।
নিনজাগেকো

@ খাচিক আমার মনে হয় এটি দ্রুত হবে তবে আমি এখন উভয় পদ্ধতির সময় পাব, পাইপলগুলি পাইথনগুলিতে খুব দ্রুত উত্পন্ন হয়।
জামিলাক

4
তৃতীয় উত্তরটি, যা অদৃশ্য হয়ে গেছে, এটি দেখতে এরকম দেখাচ্ছে: [y for x in range(n) for y in (f(x), g(x))]তবে এটি সম্ভবত ধীর। @ জামিলাক আপনি চাইলে এটিও পরীক্ষা করতে পারেন।
হাশমুশ

122

ডাবল তালিকা অনুধাবন:

[f(x) for x in range(5) for f in (f1,f2)]

ডেমো:

>>> f1 = lambda x: x
>>> f2 = lambda x: 10*x

>>> [f(x) for x in range(5) for f in (f1,f2)]
[0, 0, 1, 10, 2, 20, 3, 30, 4, 40]

12
এটি দুর্দান্ত কারণ এটি দেখায় যে ডাবল তালিকার কমপগুলি এতটা ভীতিজনক নয়: এগুলি কেবল লুপের মতো লেখা লুপগুলির জন্য বাসাযুক্তfor x in range(5): for f in (f1, f2): newlist.append(f(x))। আমি তাদেরকে কিছুটা বিভ্রান্তি হিসাবে খুঁজে পেয়েছি কারণ আমি ক্রমটি উল্টানোর চেষ্টা চালিয়ে যাচ্ছি।
ডিএসএম

4
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত, আপনাকে ধন্যবাদ, আশ্চর্যজনক!
উইংজাম

@ ডিডিএম আমি মনে করি, এটি চিরকালের জন্য বিভ্রান্তিকর হয়ে থাকবে))
উইনানড

11
sum( ([f(x),g(x)] for x in range(n)), [] )

এটি সমান [f(1),g(1)] + [f(2),g(2)] + [f(3),g(3)] + ...

আপনি এটি হিসাবে এটি ভাবতে পারেন:

def flatten(list):
    ...

flatten( [f(x),g(x)] for x in ... )

দ্রষ্টব্য: সঠিক উপায়টি হ'ল ব্যবহার করা itertools.chain.from_iterableবা ডাবল তালিকার বোধগম্যতা। (এটি প্রতিটি + এর উপরে তালিকা পুনরুদ্ধার প্রয়োজন হয় না, সুতরাং O (N) পারফরম্যান্সের পরিবর্তে O (N ^ 2) পারফরম্যান্স থাকে)) আমি sum(..., [])যখন দ্রুত ওয়ান-লাইনার চাইব বা আমি তাড়াহুড়ো করব তখনও আমি ব্যবহার করব , বা সংযুক্ত হওয়ার শর্তগুলির সংখ্যা যখন আবদ্ধ হয় (যেমন <= 10)। এই কারণেই আমি এখনও এখানে এটি উল্লেখ করছি, এই সতর্কতার সাথে। আপনি ((f(x),g(x)) for ...), ()টিউপসগুলিও ব্যবহার করতে পারেন: (বা প্রতি খচিকের মন্তব্যে, জেনারেটর এফজি (এক্স) রয়েছে যা একটি দ্বি-দ্বিগুণ ফলন দেয়)।


@ আরশথ: এটি করছে[f(1),g(1)] + [f(2),g(2)] + [f(3),g(3)] + ...
নিনজাজেকো

এটা ঠিক কি করছে তা আপনি ব্যাখ্যা করতে পারেন?
Rsh

দ্রষ্টব্য: এটিতে O (N ^ 2) রানটাইম রয়েছে যাতে এটি বিশাল তালিকাগুলিতে ধীর হতে পারে।
জামিলাক

4
@ জামিলাক: হ্যাঁ, আমি আপনার মন্তব্যেও এই উত্তরটি উল্লেখ করেছি। =)
নিনজাগেকো

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

2

এই ল্যাম্বদা ফাংশনটি একটি একক হিসাবে দুটি তালিকাকে জিপ করে:

zipped = lambda L1, L2: [L[i] 
                         for i in range(min(len(L1), len(L2))) 
                         for L in (L1, L2)]

উদাহরণ:

>>> f = [x for x in range(5)]
>>> g = [x*10 for x in range(5)]
>>> zipped(f, g)
[0, 0, 1, 10, 2, 20, 3, 30, 4, 40]

2

আমি জানি ওপি একটি তালিকা বোঝার সমাধান খুঁজছে, তবে আমি ব্যবহার করে বিকল্প প্রস্তাব করতে চাই list.extend()

f = lambda x: x
g = lambda x: 10*x

result = []
extend = result.extend
for x in range(5):
    extend((f(x),g(x)))

যা ডাবল তালিকার বোধগম্যতার তুলনায় সামান্য দ্রুত faster

nums = range(100000)

def double_comprehension():
    return [func(x) for x in nums for func in (f,g)]

def list_extend():
    result = []
    extend = result.extend
    for x in nums:
        extend((f(x),g(x)))
    return result

%timeit -n100 double_comprehension()
23.4 ms ± 67 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit -n100 list_extend()
20.5 ms ± 213 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

পাইথন সংস্করণ: 3.8.0


0

হ্রাস ব্যবহার করে একটি সমাধান :

from functools import reduce

f    = lambda x: f"f({x})" ## Just for example
g    = lambda x: f"g({x})"
data = [1, 2, 3]

reduce(lambda acc, x: acc + [f(x), g(x)], data, [])
# => ['f(1)', 'g(1)', 'f(2)', 'g(2)', 'f(3)', 'g(3)']

কোনও তালিকা বোধগম্য না হয়েও সমস্যাটি কাছে যাওয়ার এটি একটি কার্যকরী উপায়। একটি তালিকা বোধগম্যতা মূলত mapডেটা ওভার ইন করার আরেকটি উপায় , তবে এই ক্ষেত্রে যেখানে ম্যাপিং ইনপুট এবং আউটপুটটির মধ্যে এক নয় তবে reduceকীভাবে আউটপুট উত্পন্ন করা যায় তা নিয়ে কিছু উইগল রুমকে মঞ্জুরি দেয়।

সাধারণভাবে, forফর্মটির যে কোনও বাস্তবায়ন:

result = []
for n in some_data:
  result += some_operation()
  ## etc.

(উদাহরণস্বরূপ লুপগুলির জন্য কোনও তালিকা বা অনুরূপ ডেটা স্ট্রাকচারে পার্শ্ব প্রতিক্রিয়া তৈরি করার উদ্দেশ্যে)

ঘোষিত map/reduce/filterবাস্তবায়নে রিফ্যাক্টর করা যায় ।

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