2012-04-06 12 views
49

कहें कि मेरे पास अनजान लंबाई के साथ x एक सूची है जिसमें से मैं यादृच्छिक रूप से एक तत्व को पॉप करना चाहता हूं ताकि सूची में तत्व शामिल न हो। ऐसा करने के लिए सबसे अधिक पागल तरीका क्या है?किसी सूची से यादृच्छिक तत्व पॉप करने का सबसे आसान तरीका क्या है?

मैं pop, random.randint, और len की एक नहीं बल्कि असुविधाजनक combincation का उपयोग कर ऐसा कर सकते हैं और कम या अच्छे समाधान देखना चाहेंगे:

import random 
x = [1,2,3,4,5,6] 
x.pop(random.randint(0,len(x)-1)) 

संपादित करें: क्या मैं प्राप्त करने के लिए कोशिश कर रहा हूँ लगातार पॉप है एक सूची से यादृच्छिक तत्व। (यानी, बेतरतीब ढंग से एक तत्व पॉप और एक शब्दकोश पर ले जाते हैं, बेतरतीब ढंग से एक और तत्व पॉप और एक अन्य शब्दकोश पर ले जाते हैं, ...)


ध्यान दें कि मैं अजगर 2.6 का उपयोग कर रहा है और माध्यम से किसी भी समाधान नहीं मिला खोज समारोह

x.pop(random.randrange(len(x))) 

प्रलेखन पर random.randrange():

+3

मैं पाइथोनिस्टा का अधिक नहीं हूं, लेकिन यह निश्चित रूप से मेरे लिए बहुत अच्छा लग रहा है। –

उत्तर

52

आप के लिए पहली जगह में बहुत pythonic नहीं लगती है ऊपर होने लगते हैं क्या। आपको सूची के बीच से सामान को नहीं हटाया जाना चाहिए, क्योंकि सूचियों को उन सभी पायथन कार्यान्वयन में सरणी के रूप में लागू किया गया है, इसलिए यह O(n) ऑपरेशन है।

यदि आपको वास्तव में एल्गोरिदम के हिस्से के रूप में इस कार्यक्षमता की आवश्यकता है, तो आपको blist जैसे डेटा संरचना की जांच करनी चाहिए जो मध्य से कुशल हटाने का समर्थन करता है।

शुद्ध पायथन में, आप शेष तत्वों के लिए उपयोग की जरूरत नहीं है, तो सिर्फ पहली सूची शफ़ल और फिर इस पर पुनरावृति है आप क्या कर सकते:

lst = [1,2,3] 
random.shuffle(lst) 
for x in lst: 
    # ... 

आप वास्तव में शेष की जरूरत है

while lst: 
    x = lst.pop() 
    # do something with the element  

सामान्य तौर पर, आप अक्सर अपने कार्यक्रमों और अधिक सुंदर ढंग से व्यक्त कर सकते हैं: कम से कम अब आप सूची के अंत से कर सकते हैं pop() (! जो तेज है) (जो एक कोड गंध का एक सा, IMHO) यदि आप और अधिक उपयोग करते हैं कार्यात्मक शैली, राज्य को बदलने के बजाए (जैसे आप सूची के साथ करते हैं)।

+3

तो एक बेहतर (तेज़) विचार 'random.shuffle (x)' और फिर 'x.pop() 'का उपयोग करना होगा? मुझे समझ में नहीं आता कि यह "कार्यात्मक" कैसे करें? – Henrik

+0

@ हेनरिक: मुझे नहीं पता कि आप क्या करने की कोशिश कर रहे हैं, इसलिए मैं वास्तव में नहीं बता सकता। आपको प्रश्न में अधिक जानकारी जोड़नी चाहिए, या सिर्फ यहां टिप्पणी करें कि आप क्या हासिल करना चाहते हैं :) यह [XY समस्या] का एक मामला प्रतीत होता है (http://meta.stackexchange.com/questions/66377/what-is -the-xy-problem) ... –

+0

मेरे पास तत्वों की एक सूची है जिसमें से मैं लगातार यादृच्छिक तत्वों को पॉप करना चाहता हूं। – Henrik

29

आपको लगता है कि तुलना में काफी बेहतर नहीं मिलेगा, लेकिन यहाँ एक मामूली सुधार है

random.randrange ([शुरू], बंद करो [, कदम ])
range(start, stop, step) से यादृच्छिक रूप से चयनित तत्व लौटाएं। यह choice(range(start, stop, step)) के बराबर है, लेकिन वास्तव में एक श्रेणी वस्तु का निर्माण नहीं करता है।

3

एक तरह से यह करने के लिए है:

x.remove(random.choice(x)) 
+6

यदि तत्व एक बार अधिक होते हैं तो यह समस्याग्रस्त हो सकता है। –

+2

डुप्लिकेट होने पर यह बाएं तत्व को हटा देगा, जिससे पूरी तरह यादृच्छिक परिणाम नहीं होता है। – FogleBird

+0

'पॉप' के साथ आप हटाए गए तत्व पर एक नाम इंगित कर सकते हैं, इसके साथ आप नहीं कर सकते हैं। – agf

8

यहां एक और विकल्प है: आप सूची पहले क्यों नहीं बदलते हैं, और उसके बाद तब तक तत्वों को पॉप करना शुरू नहीं करते जब तक कि कोई और तत्व न रहे?इस तरह:

import random 

x = [1,2,3,4,5,6] 
random.shuffle(x) 

while x: 
    p = x.pop() 
    # do your stuff with p 
+1

से बचा जा सकता है क्यों नहीं 'x में x के लिए'? –

+3

@ निकलासबी। क्योंकि हम सूची से तत्वों को हटा रहे हैं। यदि तत्वों को निकालने के लिए बिल्कुल जरूरी नहीं है, तो मैं आपसे सहमत हूं: '[x में पी के लिए] ' –

+0

क्योंकि यह सूची बदलता है और यदि आप अभी तत्वों का आधा हिस्सा चुनना चाहते हैं और दूसरे आधा बाद में, आपके पास होगा बाद में शेष सेट। – Henrik

7

एक सूची से यादृच्छिक सूचकांक में एक एकल तत्व निकालने के लिए करता है, तो सूची तत्वों के बाकी के क्रम मायने नहीं रखता:

import random 

L = [1,2,3,4,5,6] 
i = random.randrange(len(L)) # get random index 
L[i], L[-1] = L[-1], L[i] # swap with the last element 
x = L.pop()     # pop last element O(1) 

स्वैप से बचने के लिए प्रयोग किया जाता है ओ (एन) एक सूची के बीच से हटाने पर व्यवहार।

2

सूची से पॉप-अप नहीं करते समय, मुझे डुप्लीकेट के बिना एक्स यादृच्छिक आइटम प्राप्त करने का प्रयास करते समय Google पर यह प्रश्न आया। यहाँ है कि मैं क्या अंत में इस्तेमाल किया है:

items = [1, 2, 3, 4, 5] 
items_needed = 2 
from random import shuffle 
shuffle(items) 
for item in items[:items_needed]: 
    print(item) 

यह थोड़ा अक्षम हो सकता है के रूप में आप एक पूरी सूची फेरबदल कर रहे हैं लेकिन उसके केवल एक छोटे से हिस्से का उपयोग कर, लेकिन मैं तो मैं गलत हो सकता है नहीं कर रहा हूँ एक अनुकूलन विशेषज्ञ।

+1

'random.sample (आइटम, item_needed)' – jfs

1

इस उत्तर आता है @niklas-b के सौजन्य:

... एक सूची की तरह के प्रकार:

"आप शायद pypi.python.org/pypi/blist की तरह कुछ का उपयोग करना चाहते"

PYPI page के शब्दों में बेहतर एसिम्प्टोटिक प्रदर्शन और समान छोटी सूचियों पर प्रदर्शन

ब्लिस्ट पाइथन सूची के लिए एक ड्रॉप-इन प्रतिस्थापन है जो बड़ी सूचियों को संशोधित करते समय बेहतर प्रदर्शन प्रदान करता है। ब्लिस्ट पैकेज सॉर्टेडलिस्ट, सॉर्टसेट, कमजोरोर्टेडलिस्ट, कमजोरोर्ट्ससेट, सॉर्टडिक्ट, और बीटीपल प्रकार प्रदान करता है।

एक कम ग्रहण करेंगे रैंडम एक्सेस/यादृच्छिक रन अंत पर प्रदर्शन, के रूप में यह डेटा संरचना एक "लिखने पर प्रतिलिपि" है। यह पाइथन सूचियों, पर कई उपयोग केस धारणाओं का उल्लंघन करता है, इसलिए इसे पर देखभाल के साथ उपयोग करें।

हालांकि, यदि आपका मुख्य उपयोग केस किसी सूची के साथ अजीब और अप्राकृतिक कुछ करना है (जैसा कि @OP द्वारा दिए गए जबरन उदाहरण में है, या मेरे पायथन 2.6 फीफो कतार-साथ-पास-ओवर समस्या), तो यह होगा बिल अच्छी तरह फिट करें।

0

मैं जानता हूँ कि यह एक पुराने सवाल है, लेकिन सिर्फ प्रलेखन की खातिर:

यदि आप (व्यक्ति एक ही सवाल googling) तुम क्या मुझे लगता है कि कर रहे हैं, जिसमें से बेतरतीब ढंग से वस्तुओं के कश्मीर संख्या चुन रही है, क्या कर रहे हैं एक सूची (जहां के < = लेन (आपकी सूची)), लेकिन यह सुनिश्चित करना कि प्रत्येक आइटम को एक से अधिक बार कभी नहीं चुना जाता है (= प्रतिस्थापन के बिना नमूनाकरण), आप random.sample जैसे @ जेएफ-सेबेस्टियन सुझावों का उपयोग कर सकते हैं। लेकिन उपयोग के मामले के बारे में और जानने के बिना, मुझे नहीं पता कि यह वही है जो आपको चाहिए।

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

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