টিউপসগুলির তালিকায় প্রথম উপাদান কীভাবে পাবেন?


178

আমার নীচের মতো একটি তালিকা রয়েছে যেখানে প্রথম উপাদানটি আইডি এবং অন্যটি একটি স্ট্রিং:

[(1, u'abc'), (2, u'def')]

আমি নীচের মতো কেবল এই তালিকার তালিকা থেকে আইডির একটি তালিকা তৈরি করতে চাই:

[1,2]

আমি এই তালিকাটি ব্যবহার করব __inযাতে এটির পূর্ণসংখ্যার মানগুলির তালিকা হওয়া দরকার।

উত্তর:



68

উপাদানগুলি ডিকুয়াল করতে জিপ ফাংশনটি ব্যবহার করুন:

>>> inpt = [(1, u'abc'), (2, u'def')]
>>> unzipped = zip(*inpt)
>>> print unzipped
[(1, 2), (u'abc', u'def')]
>>> print list(unzipped[0])
[1, 2]

সম্পাদনা (@ ব্র্যাডসোলোমন): উপরের পাইথন ২.x এর জন্য কাজ করে, যেখানে zipএকটি তালিকা ফিরে আসে।

পাইথন 3.x এ, zipএকটি পুনরাবৃত্তি প্রদান করে এবং নিম্নলিখিতটি উপরের সমতুল্য:

>>> print(list(list(zip(*inpt))[0]))
[1, 2]

এর কি আলাদা আমদানি দরকার?
জুলিয়ানডোটনট

2
@ জুলিয়াডোটনট না, এটি একটি অন্তর্নির্মিত ফাংশন। (পাইথন ২.x এ)
ওয়েনসান

22

তুমি কি এরকম কিছু বোঝাতে চাও?

new_list = [ seq[0] for seq in yourlist ]

আপনার কাছে যা আছে তা হ'ল tupleঅবজেক্টের একটি তালিকা, সেটগুলির তালিকা নয় (আপনার মূল প্রশ্নটি ইঙ্গিত করা হয়েছে)। যদি এটি প্রকৃতপক্ষে সেটগুলির একটি তালিকা হয় তবে তারপরে কোনও প্রথম উপাদান নেই কারণ সেটের কোনও অর্ডার নেই।

এখানে আমি একটি সমতল তালিকা তৈরি করেছি কারণ সাধারণত এটি 1 টি এলিমেন্ট টিপলগুলির তালিকা তৈরির চেয়ে বেশি কার্যকর বলে মনে হয়। যাইহোক, আপনি খুব সহজেই মাত্র প্রতিস্থাপন 1 উপাদান tuples একটি তালিকা তৈরি করতে পারেন seq[0]সঙ্গে (seq[0],)


আমি এটা চেষ্টা করেছি. এটি এই ত্রুটিটি দেয়:int() argument must be a string or a number, not 'QuerySet'

4
@ ওসিম্বল্লি - int()আমার সমাধানের কোথাও নেই, তাই আপনি যে ব্যতিক্রম দেখছেন তা অবশ্যই কোডে পরে আসতে হবে।
মিগিলসন

আমি প্রশ্নটি আপডেট করেছি, __inডেটা ফিল্টার করার জন্য আমার এই তালিকাটি পরে ব্যবহার করতে হবে
ওয়াসিম্বল্লি

কি __in? - আপনি যে উদাহরণটি দিয়েছেন তার উপর ভিত্তি করে এটি পূর্ণসংখ্যার একটি তালিকা তৈরি করবে। তবে, যদি আপনার তালিকার তালিকাটি পূর্ণসংখ্যার সাথে শুরু হয় না, তবে আপনি পূর্ণসংখ্যা পাবেন না এবং আপনাকে তাদের মাধ্যমে পূর্ণসংখ্যার তৈরি করতে হবে int, বা আপনার প্রথম উপাদানটি কেন পূর্ণসংখ্যায় রূপান্তর করা যাবে না তা বোঝার চেষ্টা করবেন।
মিগিলসন

নেই new_list = [ seq[0] for seq in yourlist if type(seq[0]) == int]কাজ করে?
pR0Ps

11

আপনি "টিপল আনপ্যাকিং" ব্যবহার করতে পারেন:

>>> my_list = [(1, u'abc'), (2, u'def')]
>>> my_ids = [idx for idx, val in my_list]
>>> my_ids
[1, 2]

পুনরাবৃত্তির সময় প্রতিটি টিপল আনপ্যাক করা থাকে এবং এর মানগুলি ভেরিয়েবল idxএবং এ সেট করা হয় val

>>> x = (1, u'abc')
>>> idx, val = x
>>> idx
1
>>> val
u'abc'

8

এই কি operator.itemgetterজন্য হয়।

>>> a = [(1, u'abc'), (2, u'def')]
>>> import operator
>>> b = map(operator.itemgetter(0), a)
>>> b
[1, 2]

itemgetterবিবৃতি একটি ফাংশন ফেরৎ যে উপাদান আপনাকে তা নির্দিষ্ট সূচক ফেরৎ। এটি লেখার মতোই

>>> b = map(lambda x: x[0], a)

তবে আমি দেখতে পাচ্ছি যে itemgetterএটি পরিষ্কার এবং আরও স্পষ্ট

এটি কমপ্যাক্ট সাজানোর বিবৃতি দেওয়ার জন্য কার্যকর hand উদাহরণ স্বরূপ,

>>> c = sorted(a, key=operator.itemgetter(0), reverse=True)
>>> c
[(2, u'def'), (1, u'abc')]

7

পাইথন 3. এক্স-এ পারফরম্যান্সের দিক থেকে

  • [i[0] for i in a]এবং list(zip(*a))[0]সমতুল্য
  • তারা তুলনায় দ্রুত list(map(operator.itemgetter(0), a))

কোড

import timeit


iterations = 100000
init_time = timeit.timeit('''a = [(i, u'abc') for i in range(1000)]''', number=iterations)/iterations
print(timeit.timeit('''a = [(i, u'abc') for i in range(1000)]\nb = [i[0] for i in a]''', number=iterations)/iterations - init_time)
print(timeit.timeit('''a = [(i, u'abc') for i in range(1000)]\nb = list(zip(*a))[0]''', number=iterations)/iterations - init_time)

আউটপুট

3.491014136001468e-05

3.422205176000717e-05


6

যদি টিপলগুলি অনন্য হয় তবে এটি কাজ করতে পারে

>>> a = [(1, u'abc'), (2, u'def')]
>>> a
[(1, u'abc'), (2, u'def')]
>>> dict(a).keys()
[1, 2]
>>> dict(a).values()
[u'abc', u'def']
>>> 

4
এটি অর্ডারটি হারাবে। ordereddictযদিও এটি সাথে কাজ করতে পারে ।
টিম টিসডাল

যদি 2 বা ততোধিক
টিউপলসের সাথে

3

যখন আমি দৌড়েছি (উপরে প্রস্তাবিত হিসাবে):

>>> a = [(1, u'abc'), (2, u'def')]
>>> import operator
>>> b = map(operator.itemgetter(0), a)
>>> b

পরিবর্তে ফিরে:

[1, 2]

আমি এটি রিটার্ন হিসাবে পেয়েছি:

<map at 0xb387eb8>

আমি দেখতে পেলাম আমার তালিকা ব্যবহার করতে হয়েছে ():

>>> b = list(map(operator.itemgetter(0), a))

সফলভাবে এই পরামর্শ ব্যবহার করে একটি তালিকা ফিরে। বলেছিল, আমি এই সমাধানে খুশি, ধন্যবাদ। (স্পাইডার, আইপথন কনসোল, পাইথন ভি .6..6 ব্যবহার করে পরীক্ষিত / চালানো)


3

আমি ভাবছিলাম যে বিভিন্ন পদ্ধতির রানটাইমের তুলনা করা কার্যকর হতে পারে তাই আমি একটি বেঞ্চমার্ক তৈরি করেছি ( সরল_ব্যাঞ্চমার্ক লাইব্রেরি ব্যবহার করে )

আমি) বেঞ্চমার্কে 2 টি উপাদান রয়েছে up এখানে চিত্র বর্ণনা লিখুন

যেমন আপনি সূচক অনুসারে টিপলস থেকে প্রথম উপাদানটি বেছে নেওয়ার প্রত্যাশা করতে পারেন 0ঠিক ঠিক 2 মান প্রত্যাশা করে আনপ্যাকিং সমাধানের খুব দ্রুত সমাধান হতে দেখায়

import operator
import random

from simple_benchmark import BenchmarkBuilder

b = BenchmarkBuilder()



@b.add_function()
def rakesh_by_index(l):
    return [i[0] for i in l]


@b.add_function()
def wayneSan_zip(l):
    return list(list(zip(*l))[0])


@b.add_function()
def bcattle_itemgetter(l):
     return list(map(operator.itemgetter(0), l))


@b.add_function()
def ssoler_upacking(l):
    return [idx for idx, val in l]

@b.add_function()
def kederrack_unpacking(l):
    return [f for f, *_ in l]



@b.add_arguments('Number of tuples')
def argument_provider():
    for exp in range(2, 21):
        size = 2**exp
        yield size, [(random.choice(range(100)), random.choice(range(100))) for _ in range(size)]


r = b.run()
r.plot()

দ্বিতীয়) বেঞ্চমার্কে 2 বা ততোধিক উপাদান রয়েছে up এখানে চিত্র বর্ণনা লিখুন

import operator
import random

from simple_benchmark import BenchmarkBuilder

b = BenchmarkBuilder()

@b.add_function()
def kederrack_unpacking(l):
    return [f for f, *_ in l]


@b.add_function()
def rakesh_by_index(l):
    return [i[0] for i in l]


@b.add_function()
def wayneSan_zip(l):
    return list(list(zip(*l))[0])


@b.add_function()
def bcattle_itemgetter(l):
     return list(map(operator.itemgetter(0), l))


@b.add_arguments('Number of tuples')
def argument_provider():
    for exp in range(2, 21):
        size = 2**exp
        yield size, [tuple(random.choice(range(100)) for _
                     in range(random.choice(range(2, 100)))) for _ in range(size)]

from pylab import rcParams
rcParams['figure.figsize'] = 12, 7

r = b.run()
r.plot()


0

আপনি আপনার টিপলগুলি আনপ্যাক করতে পারেন এবং তালিকা অনুধাবন ব্যবহার করে কেবলমাত্র প্রথম উপাদানটি পেতে পারেন :

l = [(1, u'abc'), (2, u'def')]
[f for f, *_ in l]

আউটপুট:

[1, 2]

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

l = [(1, u'abc'), (2, u'def', 2, 4, 5, 6, 7)]
[f for f, *_ in l]

আউটপুট:

[1, 2]

0

আমি অবাক হয়েছি কেন কেন কেউ ন্যাপি ব্যবহার করার পরামর্শ দেয়নি, তবে এখন পরীক্ষার পরে আমি বুঝতে পারি। এটি মিশ্র টাইপের অ্যারেগুলির জন্য সেরা নয় not

এটি অদ্ভুত একটি সমাধান হবে:

>>> import numpy as np

>>> a = np.asarray([(1, u'abc'), (2, u'def')])
>>> a[:, 0].astype(int).tolist()
[1, 2]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.