2013-06-02 8 views
11

मैं पाइथन के लिए काफी नया हूं, और सोचें कि यह एक आम समस्या है, लेकिन समाधान नहीं मिल रहा है। मैंने पहले से ही this page पर देखा है और इसे एक आइटम के लिए उपयोगी पाया है, लेकिन मैं 'फॉर' लूप का उपयोग किये बिना कई आइटमों का उदाहरण बढ़ाने के लिए संघर्ष कर रहा हूं। मैं एसी के माध्यम से 250 वॉकर के लिए कोड का यह छोटा सा भाग चला रहा हूं, इसलिए मैं सबसे तेज़ तरीका ढूंढ रहा हूं।अलग-अलग सूची आइटमों की सूची बनाना गुणा n12

मैं, a = [x,y,z] कि मैं b = [1,2,3] बार (उदाहरण के लिए) दोहराना चाहते नंबरों की सूची है, तो मैं सूचियों की सूची के साथ अंत:

[ 
[x], 
[y,y], 
[z,z,z] 
] 

'के लिए' पाश मेरे पास है:

c = [ ] 
for i in range (0,len(a)): 
    c.append([a[i]]*b[i]) 

जो वास्तव में मैं चाहता हूं, लेकिन मेरा मतलब है कि मेरा कोड बेहद धीमा है। मैंने एरे में ए और बी को निष्क्रिय रूप से बदलने और [a]*b करने की उम्मीद में भी कोशिश की है कि यह तत्व द्वारा तत्व को गुणा करेगी, लेकिन कोई खुशी नहीं होगी।

उत्तर

10

आप zip और यहाँ एक सूची समझ का उपयोग कर सकते हैं:

>>> a = ['x','y','z'] 
>>> b = [1,2,3] 
>>> [[x]*y for x,y in zip(a,b)] 
[['x'], ['y', 'y'], ['z', 'z', 'z']] 

या:

>>> [[x for _ in xrange(y)] for x,y in zip(a,b)] 
[['x'], ['y', 'y'], ['z', 'z', 'z']] 

zip, पहले स्मृति में पूरी सूची बनाएगा पुनरावर्तक का उपयोग पाने के लिए itertools.izip

यदि a में सूचियों या सूचियों की सूचियों जैसे म्यूटेबल ऑब्जेक्ट्स हैं, तो आपकोका उपयोग करना पड़ सकता हैयहाँ क्योंकि एक प्रतिलिपि को संशोधित करने के अन्य प्रतियां रूप में अच्छी तरह .:

>>> from copy import deepcopy as dc 
>>> a = [[1 ,4],[2, 5],[3, 6, 9]] 
>>> f = [[dc(x) for _ in xrange(y)] for x,y in zip(a,b)] 

#now all objects are unique 
>>> [[id(z) for z in x] for x in f] 
[[172880236], [172880268, 172880364], [172880332, 172880492, 172880428]] 
बदल जाएगा

timeit तुलना (अनदेखी आयात):

>>> a = ['x','y','z']*10**4 
>>> b = [100,200,300]*10**4 

>>> %timeit [[x]*y for x,y in zip(a,b)] 
1 loops, best of 3: 104 ms per loop 

>>> %timeit [[x]*y for x,y in izip(a,b)] 
1 loops, best of 3: 98.8 ms per loop 

>>> %timeit map(lambda v: [v[0]]*v[1], zip(a,b)) 
1 loops, best of 3: 114 ms per loop 

>>> %timeit map(list, map(repeat, a, b)) 
1 loops, best of 3: 192 ms per loop 

>>> %timeit map(list, imap(repeat, a, b)) 
1 loops, best of 3: 211 ms per loop 

>>> %timeit map(mul, [[x] for x in a], b) 
1 loops, best of 3: 107 ms per loop 

>>> %timeit [[x for _ in xrange(y)] for x,y in zip(a,b)] 
1 loops, best of 3: 645 ms per loop 

>>> %timeit [[x for _ in xrange(y)] for x,y in izip(a,b)] 
1 loops, best of 3: 680 ms per loop 
+1

मैं 'itertools.izip' का उल्लेख करने का सुझाव दूंगा। – kirelagin

+1

धन्यवाद! क्या 'फॉर' लूप अभी भी कोड को धीमा कर देगा, यद्यपि? – user2444731

+0

@ user2444731 आपका क्या मतलब है "धीमा"? आपको लगता है कि 'लूप' धीमा क्यों है? क्या तुलना में धीमा? – kirelagin

1

यहाँ for छोरों के बिना एक संस्करण है, तो आप उनके लिए पसंद नहीं है है किसी कारण:

map(lambda v: [v[0]]*v[1], zip(a,b)) 

मैं आपको यह भी चेतावनी चाहिए इस संस्करण एक सूची समझ की तुलना में थोड़ा धीमी है कि:

$ a = ['hi']*100 
$ b = [20]*100 

$ %timeit map(lambda v: [v[0]]*v[1], zip(a,b)) 
10000 loops, best of 3: 101 us per loop 

%timeit [[x]*y for x,y in zip(a,b)] 
10000 loops, best of 3: 74.1 us per loop 

मैं भी zip के बजाय itertools.izip का उपयोग कर की सलाह देते हैं अगर तुम अजगर पर हैं 2.

2

@kirelagin for छोरों के बिना एक संस्करण का सुझाव दिया, कि यहाँ भी (lambda रों नहीं है रखें एक है मन @AshwiniChaudhary द्वारा समाधान सबसे पढ़ी जा सकती है)

>>> from itertools import repeat 
>>> a = ['x','y','z'] 
>>> b = [1,2,3] 
>>> map(list, map(repeat, a, b)) 
[['x'], ['y', 'y'], ['z', 'z', 'z']] 

>>> map(repeat, a, b) 
[repeat('x', 1), repeat('y', 2), repeat('z', 3)] 

repeat ऑब्जेक्ट्स की एक सूची बनाता है (पायथन 2 पर imap का उपयोग करें।एक्स अगर आप किसी सूची के बजाय आलसी इटरेटर चाहते हैं) जो स्मृति में कोई अतिरिक्त जगह नहीं लेता है, तो यह बहुत अच्छा है अगर आप उन्हें स्टोर करने के बजाय आइटम पर फिर से चालू करना चाहते हैं)

5

करने का सबसे तेज़ तरीका यह map() और operator.mul() साथ है:

>>> from operator import mul 
>>> map(mul, [['x'], ['y'], ['z']], [1, 2, 3]) 
[['x'], ['y', 'y'], ['z', 'z', 'z']] 
+3

+1 मैंने इसे पोस्ट करते समय यह पता लगाया (इनपुट इनपुट की सूची नहीं है) – jamylak

3
>>> from itertools import repeat 
>>> from itertools import starmap 
>>> a = ['x','y','z'] 
>>> b = [1,2,3] 
>>> starmap(repeat,zip(a,b)) 

starmap एक iterable देता है जो एक टपल में निहित मूल्यों के बराबर तर्क के साथ repeat बुला, उदाहरण के ('x',1) के लिए इस मामले में के परिणाम के बराबर मान हैं।

>>> for p in starmap(repeat,zip(a,b)): 
    print(list(p)) 


['x'] 
['y', 'y'] 
['z', 'z', 'z'] 
+0

ध्यान दें कि आपको 'starmap' पर 'map (list, ...)' को कॉल करना होगा सूचियों की सूची प्राप्त करें – jamylak

संबंधित मुद्दे