python তালিকা তালিকা থেকে একটি সমতল তালিকা কিভাবে?





15 Answers

আপনি itertools.chain() ব্যবহার করতে পারেন:

>>> import itertools
>>> list2d = [[1,2,3],[4,5,6], [7], [8,9]]
>>> merged = list(itertools.chain(*list2d))

অথবা, পাইথন> = 2.6 এ, itertools.chain.from_iterable() ব্যবহার করুন যা তালিকার আনপ্যাকিংয়ের প্রয়োজন নেই:

>>> import itertools
>>> list2d = [[1,2,3],[4,5,6], [7], [8,9]]
>>> merged = list(itertools.chain.from_iterable(list2d))

এই পদ্ধতিটি বিতর্কিতভাবে তুলনায় আরও বেশি [item for sublist in l for item in sublist] এবং আরও দ্রুত বলে মনে হচ্ছে:

[me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99;import itertools' 'list(itertools.chain.from_iterable(l))'
10000 loops, best of 3: 24.2 usec per loop
[me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 45.2 usec per loop
[me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 3: 488 usec per loop
[me@home]$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 3: 522 usec per loop
[me@home]$ python --version
Python 2.7.3
python list multidimensional-array flatten

Python এ তালিকাগুলির তালিকা থেকে একটি সহজ তালিকা তৈরি করার জন্য একটি শর্টকাট আছে কিনা আমি অবাক।

আমি একটি লুপ জন্য যে করতে পারেন, কিন্তু সম্ভবত কিছু শীতল "এক-মাছ ধরার নৌকা" আছে? আমি এটি কমাতে চেষ্টা করেছি, কিন্তু আমি একটি ত্রুটি পেতে।

কোড

l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
reduce(lambda x, y: x.extend(y), l)

ভুল বার্তা

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
AttributeError: 'NoneType' object has no attribute 'extend'



আমি perfplot (খনি একটি পোষা প্রকল্প, মূলত timeit কাছাকাছি একটি wrapper) সঙ্গে সবচেয়ে প্রস্তাবিত সমাধান পরীক্ষা, এবং পাওয়া যায়

list(itertools.chain.from_iterable(a))

দ্রুততম সমাধান হতে (যদি 10 টির বেশি তালিকা সংহত হয়)।

প্লট পুনরুত্পাদন কোড:

import functools
import itertools
import numpy
import operator
import perfplot


def forfor(a):
    return [item for sublist in a for item in sublist]


def sum_brackets(a):
    return sum(a, [])


def functools_reduce(a):
    return functools.reduce(operator.concat, a)


def itertools_chain(a):
    return list(itertools.chain.from_iterable(a))


def numpy_flat(a):
    return list(numpy.array(a).flat)


def numpy_concatenate(a):
    return list(numpy.concatenate(a))


perfplot.show(
    setup=lambda n: [list(range(10))] * n,
    kernels=[
        forfor, sum_brackets, functools_reduce, itertools_chain, numpy_flat,
        numpy_concatenate
        ],
    n_range=[2**k for k in range(16)],
    logx=True,
    logy=True,
    xlabel='num lists'
    )



এখানে একটি সাধারণ পদ্ধতি যা সংখ্যা , স্ট্রিং , নেস্টেড তালিকা এবং মিশ্র পাত্রে প্রয়োগ করা হয়।

কোড

from collections import Iterable


def flatten(items):
    """Yield items from any nested iterable; see Reference."""
    for x in items:
        if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
            for sub_x in flatten(x):
                yield sub_x
        else:
            yield x

দ্রষ্টব্য: পাইথন 3 এ, for sub_x in flatten(x): yield sub_x yield from flatten(x) প্রতিস্থাপন করতে পারে for sub_x in flatten(x): yield sub_x

ডেমো

lst = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
list(flatten(lst))                                         # nested lists
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

mixed = [[1, [2]], (3, 4, {5, 6}, 7), 8, "9"]              # numbers, strs, nested & mixed
list(flatten(mixed))
# [1, 2, 3, 4, 5, 6, 7, 8, '9']

উল্লেখ

  • এই সমাধানটি Beazley, D. এবং B. জোন্সের রেসিপি থেকে সংশোধন করা হয় রেসিপি 4.14, পাইথন কুকবুক 3 য় এড।, ও'রাইলি মিডিয়া ইনক। সেবাস্তোপোল, সিএ: 2013।
  • একটি পূর্ববর্তী SO পোস্ট , সম্ভবত মূল বিক্ষোভ পাওয়া গেছে।



আপনি প্রসারিত ব্যবহার করবেন কেন?

reduce(lambda x, y: x+y, l)

এই জরিমানা কাজ করা উচিত।




অপারেটিং.ড্ড দিয়ে একটি বিভ্রান্তি বলে মনে হচ্ছে! যখন আপনি একসাথে দুটি তালিকা যুক্ত করেন, তখন তার জন্য সঠিক শব্দটি যোগ করা হয় না। operator.concat আপনি ব্যবহার করতে হবে কি।

যদি আপনি কার্যকরী চিন্তা করছেন, এটি এই হিসাবে সহজ:

>>> list2d = ((1, 2, 3), (4, 5, 6), (7,), (8, 9))
>>> reduce(operator.concat, list2d)
(1, 2, 3, 4, 5, 6, 7, 8, 9)

আপনি ক্রম টাইপ সম্মান কমাতে দেখুন, তাই যখন আপনি একটি tuple সরবরাহ, আপনি একটি tuple ফিরে পেতে। এর একটি তালিকা দিয়ে চেষ্টা করা যাক ::

>>> list2d = [[1, 2, 3],[4, 5, 6], [7], [8, 9]]
>>> reduce(operator.concat, list2d)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

আহ, আপনি একটি তালিকা ফিরে পেতে।

কর্মক্ষমতা সম্পর্কে কিভাবে ::

>>> list2d = [[1, 2, 3],[4, 5, 6], [7], [8, 9]]
>>> %timeit list(itertools.chain.from_iterable(list2d))
1000000 loops, best of 3: 1.36 µs per loop

from_iterable বেশ দ্রুত! কিন্তু এটি concat সঙ্গে কমাতে কোন তুলনা।

>>> list2d = ((1, 2, 3),(4, 5, 6), (7,), (8, 9))
>>> %timeit reduce(operator.concat, list2d)
1000000 loops, best of 3: 492 ns per loop



more_itertools প্যাকেজ ইনস্টল করার কথা বিবেচনা করুন।

> pip install more_itertools

এটি flatten জন্য একটি বাস্তবায়ন সঙ্গে জাহাজ ( source , itertools রেসিপি থেকে ):

import more_itertools


lst = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
list(more_itertools.flatten(lst))
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

সংস্করণ 2.4 হিসাবে, আপনি আরো জটিল, nested more_itertools.collapse ( source , অবরনেট দ্বারা অবদান) দিয়ে more_itertools.collapse করতে পারেন।

lst = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
list(more_itertools.collapse(lst)) 
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

lst = [[1, 2, 3], [[4, 5, 6]], [[[7]]], 8, 9]              # complex nesting
list(more_itertools.collapse(lst))
# [1, 2, 3, 4, 5, 6, 7, 8, 9]



def flatten(l, a):
    for i in l:
        if isinstance(i, list):
            flatten(i, a)
        else:
            a.append(i)
    return a

print(flatten([[[1, [1,1, [3, [4,5,]]]], 2, 3], [4, 5],6], []))

# [1, 1, 1, 3, 4, 5, 2, 3, 4, 5, 6]



কেউ নুম্পির flat ব্যবহার করতে পারে:

import numpy as np
list(np.array(l).flat)

সম্পাদন 11/02/2016: শুধুমাত্র sublists অভিন্ন মাত্রা আছে যখন কাজ করে।




underscore.py প্যাকেজ ফ্যানের জন্য সহজ কোড

from underscore import _
_.flatten([[1, 2, 3], [4, 5, 6], [7], [8, 9]])
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

এটি সমস্ত flatten সমস্যার সমাধান (কোন তালিকা আইটেম বা জটিল নেস্টিং)

from underscore import _
# 1 is none list item
# [2, [3]] is complex nesting
_.flatten([1, [2, [3]], [4, 5, 6], [7], [8, 9]])
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

আপনি underscore.py দিয়ে ইনস্টল করতে পারেন

pip install underscore.py



পরিবর্তনশীল উত্তর টেক্সট-ভিত্তিক তালিকা মোকাবেলা করার সময় গৃহীত উত্তর আমার জন্য কাজ করে না। এখানে আমার জন্য কাজ করে যে একটি বিকল্প পদ্ধতির।

l = ['aaa', 'bb', 'cccccc', ['xx', 'yyyyyyy']]

গৃহীত উত্তর যে কাজ করে না :

flat_list = [item for sublist in l for item in sublist]
print(flat_list)
['a', 'a', 'a', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c', 'xx', 'yyyyyyy']

নতুন প্রস্তাবিত সমাধান যা আমার জন্য কাজ করেছে:

flat_list = []
_ = [flat_list.extend(item) if isinstance(item, list) else flat_list.append(item) for item in l if item]
print(flat_list)
['aaa', 'bb', 'cccccc', 'xx', 'yyyyyyy']



আপনি যদি ক্লিনার চেহারাটির জন্য একটি ক্ষুদ্র গতির গতি ছেড়ে দিতে ইচ্ছুক হন তবে আপনি numpy.concatenate().tolist() অথবা numpy.concatenate().ravel().tolist() ব্যবহার করতে পারেন numpy.concatenate().ravel().tolist()

import numpy

l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]] * 99

%timeit numpy.concatenate(l).ravel().tolist()
1000 loops, best of 3: 313 µs per loop

%timeit numpy.concatenate(l).tolist()
1000 loops, best of 3: 312 µs per loop

%timeit [item for sublist in l for item in sublist]
1000 loops, best of 3: 31.5 µs per loop

আপনি ডক্স numpy.concatenate এবং numpy.ravel ডক্স এখানে আরও জানতে পারেন




হিটের জন্য কাজ করে এমন আরেকটি অস্বাভাবিক পদ্ধতি- এবং পূর্ণসংখ্যার একক তালিকা:

from typing import List


def flatten(l: list) -> List[int]:
    """Flatten an arbitrary deep nested list of lists of integers.

    Examples:
        >>> flatten([1, 2, [1, [10]]])
        [1, 2, 1, 10]

    Args:
        l: Union[l, Union[int, List[int]]

    Returns:
        Flatted list of integer
    """
    return [int(i.strip('[ ]')) for i in str(l).split(',')]



আমি সম্প্রতি একটি পরিস্থিতি জুড়ে এসেছি যেখানে আমি যেমন sublists মধ্যে স্ট্রিং এবং সংখ্যাসূচক তথ্য মিশ্রিত ছিল

test = ['591212948',
['special', 'assoc', 'of', 'Chicago', 'Jon', 'Doe'],
['Jon'],
['Doe'],
['fl'],
92001,
555555555,
'hello',
['hello2', 'a'],
'b',
['hello33', ['z', 'w'], 'b']]

যেখানে পদ্ধতি flat_list = [item for sublist in test for item in sublist]কাজ করে না। তাই, আমি 1+ স্তরের sublists জন্য নিচের সমাধান নিয়ে এসেছি

def concatList(data):
    results = []
    for rec in data:
        if type(rec) == list:
            results += rec
            results = concatList(results)
        else:
            results.append(rec)
    return results

এবং ফলাফল

In [38]: concatList(test)
Out[38]:
 Out[60]:
['591212948',
'special',
'assoc',
'of',
'Chicago',
'Jon',
'Doe',
'Jon',
'Doe',
'fl',
92001,
555555555,
'hello',
'hello2',
'a',
'b',
'hello33',
'z',
'w',
'b']



আপনি বেশ সহজভাবে একটি প্রকৃত স্ট্যাক তথ্য গঠন ব্যবহার করে স্ট্যাকের recursive কল এড়াতে পারেন।

alist = [1,[1,2],[1,2,[4,5,6],3, "33"]]
newlist = []

while len(alist) > 0 :
  templist = alist.pop()
  if type(templist) == type(list()) :
    while len(templist) > 0 :
      temp = templist.pop()
      if type(temp) == type(list()) :
        for x in temp :
          templist.append(x)
      else :
        newlist.append(temp)
  else :
    newlist.append(templist)
print(list(reversed(newlist)))



তালিকা reduceথেকে functoolsএবং addঅপারেটর ব্যবহার করে একটি সহজ recursive পদ্ধতি :

>>> from functools import reduce
>>> from operator import add
>>> flatten = lambda lst: [lst] if type(lst) is int else reduce(add, [flatten(ele) for ele in lst])
>>> flatten(l)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

ফাংশন হিসাবে পরামিতি flattenলাগে lst। এটা সব উপাদান loops lstপর্যন্ত পৌঁছনো পূর্ণসংখ্যার (এছাড়াও পরিবর্তন করতে পারেন intথেকে float, strযা দূরতম পুনরাবৃত্তির ফেরত মান যোগ করা হয় অন্য ডেটা ধরনের জন্য, ইত্যাদি)।

forলুপ এবং মণ্যাডের মতো পদ্ধতির বিপরীতে , এটি একটি সাধারণ সমাধান তালিকা গভীরতার দ্বারা সীমাবদ্ধ নয় । উদাহরণস্বরূপ, 5 এর গভীরতা সহ একটি তালিকা একইভাবে ফ্ল্যাট করা যেতে পারে l:

>>> l2 = [[3, [1, 2], [[[6], 5], 4, 0], 7, [[8]], [9, 10]]]
>>> flatten(l2)
[3, 1, 2, 6, 5, 4, 0, 7, 8, 9, 10]



Related