অবজেক্টের একটি তালিকা বদলানো


769

আমার কাছে অবজেক্টের একটি তালিকা রয়েছে এবং আমি সেগুলি বদলাতে চাই। আমি ভেবেছিলাম আমি random.shuffleপদ্ধতিটি ব্যবহার করতে পারি , তবে তালিকাটি যখন বস্তুগুলির হয় তখন এটি ব্যর্থ হয়। জিনিসপত্র বদল করার জন্য কোনও উপায় আছে বা এর চারপাশে অন্য কোনও উপায়?

import random

class A:
    foo = "bar"

a1 = a()
a2 = a()
b = [a1, a2]

print(random.shuffle(b))

এটি ব্যর্থ হবে।


6
কীভাবে এটি ব্যর্থ হয় আপনি একটি উদাহরণ দিতে পারেন? random.shuffle তালিকার অবজেক্টের ধরণের জন্য অদম্য কাজ করা উচিত।
বায়ার

3
>>> এ 1 = এ () >>> এ 2 = এ () >>> বি = [এ 1, এ 2] >>> বি [<__ প্রধান __। 0xb7df9e6c> এর একটি উদাহরণ, <__ প্রধান __। 0xb7df9e2c>> তে একটি উদাহরণ >> এলোমেলো.স্যাফেল মুদ্রণ (খ) কিছুই নেই
উডিস্কেন্ট

135
নীচে বর্ণিত হিসাবে, এলোমেলো.স্যাফল একটি নতুন শিফলেড তালিকা ফেরত দেয় না; এটি তালিকায় স্থান পরিবর্তন করে। সুতরাং আপনার "প্রিন্ট এলোমেলো.স্যাফেল (বি)" বলা উচিত নয় এবং পরিবর্তে এক লাইনে এলোমেলো করা উচিত এবং পরবর্তী লাইনে বি মুদ্রণ করা উচিত।
এলি কোর্টরাইট

আপনি যদি নাম্বার অ্যারে বদলানোর চেষ্টা করছেন তবে নীচে আমার উত্তর দেখুন।
গর্ডন বিন

1
এমন কোনও বিকল্প রয়েছে যা মূল অ্যারেটি পরিবর্তন করতে পারে না তবে নতুন বদলানো অ্যারেটি ফেরত দেবে?
চার্লি পার্কার

উত্তর:


1240

random.shuffleকাজ করা উচিত. এখানে উদাহরণ রয়েছে, যেখানে বস্তুগুলি তালিকাভুক্ত রয়েছে:

from random import shuffle
x = [[i] for i in range(10)]
shuffle(x)

# print(x)  gives  [[9], [2], [7], [0], [4], [5], [3], [1], [8], [6]]
# of course your results will vary

নোট করুন যে বদলানো কাজ করে বদলে যাওয়া জায়গায় করে এবং কোনও কিছুই দেয় না।


1
পুনঃটুইট এটি একটি pseduo- এলোমেলো সংখ্যা জেনারেটর যা সম্ভব হলে ওএস থেকে বাস্তব এলোমেলো উত্স দ্বারা বদ্ধ হয়। সকলের জন্য ক্রিপ্টোগ্রাফি উদ্দেশ্যে এটি এলোমেলো "যথেষ্ট"। এটি randomমডিউলটির ডকুমেন্টেশনে বিশদভাবে উল্লেখ করা হয়েছে
ডিমো 414

2
নতুন তালিকার জন্য ক্লোন ব্যবহার করুন
মোহাম্মদ মাহদী কাউচাক ইয়াজদি

8
এমন কোনও বিকল্প রয়েছে যা মূল অ্যারেটি পরিবর্তন করতে পারে না তবে নতুন বদলানো অ্যারেটি ফেরত দেবে?
চার্লি পার্কার

5
@ চার্লিপার্কার: আমার জানা নেই Not আপনি ব্যবহার করতে পারেন random.sample(x, len(x))বা কেবল একটি অনুলিপি তৈরি করতে পারেন shufflethat list.sortযার জন্য একই ধরণের সমস্যা রয়েছে, এখন list.sortedআছে তবে এর মতো কোনও বৈকল্পিক নেই shuffle
tom10

6
ক্রিপ্টো-সুরক্ষিত এলোমেলোতার জন্য @ Seokhonlee, from random import SystemRandomপরিবর্তে ব্যবহার করুন; cryptorand = SystemRandom()3 থেকে সারি 3 যোগ করুন এবং পরিবর্তন করুনcryptorand.shuffle(x)
ব্রাউজ করুন

115

আপনি যেমন শিখেছিলেন জায়গায় জায়গা বদলানো সমস্যা ছিল। আমারও প্রায়শই সমস্যা হয় এবং প্রায়শই কীভাবে কোনও তালিকা অনুলিপি করতে হয় তাও ভুলে যায় বলে মনে করি। ব্যবহার sample(a, len(a)), সমাধান ব্যবহার len(a)নমুনা আকার। পাইথন ডকুমেন্টেশনের জন্য https://docs.python.org/3.6/library/random.html#random.sample দেখুন ।

এখানে এমন একটি সাধারণ সংস্করণ ব্যবহার করা হচ্ছে random.sample()যা বদলে যাওয়া ফলটিকে নতুন তালিকা হিসাবে ফিরিয়ে দেয়।

import random

a = range(5)
b = random.sample(a, len(a))
print a, b, "two list same:", a == b
# print: [0, 1, 2, 3, 4] [2, 1, 3, 4, 0] two list same: False

# The function sample allows no duplicates.
# Result can be smaller but not larger than the input.
a = range(555)
b = random.sample(a, len(a))
print "no duplicates:", a == list(set(b))

try:
    random.sample(a, len(a) + 1)
except ValueError as e:
    print "Nope!", e

# print: no duplicates: True
# print: Nope! sample larger than population

এমন কোনও বিকল্প রয়েছে যা মূল অ্যারেটি পরিবর্তন করতে পারে না তবে নতুন বদলানো অ্যারেটি ফেরত দেবে?
চার্লি পার্কার

কেবলমাত্র তালিকাটি কপি করুন @ চর্লিপার্কার: old = [1,2,3,4,5]; new = list(old); random.shuffle(new); print(old); print(new)(প্রতিস্থাপন করুন;
নতুনলাইনগুলি

old[:]এছাড়াও তালিকার জন্য অগভীর অনুলিপি করতে পারে old
জিয়াও

sample()ডেটা বিশ্লেষণের প্রোটোটাইপিংয়ের জন্য বিশেষভাবে সহায়ক। sample(data, 2)একটি পাইপলাইনের আঠালো কোড স্থাপনের জন্য, তারপরে এটি ধাপ অনুসারে "প্রশস্ত" করুন len(data)
ক্যাটরিন লাইনওয়েবার

58

এটি পেতে আমার কিছুটা সময় লেগেছিল। তবে রদবদলের জন্য ডকুমেন্টেশন খুব স্পষ্ট:

জায়গায় স্থান বদলের তালিকা ; কোনটিই ফেরেনি

সুতরাং আপনি করা উচিত নয় print(random.shuffle(b))। পরিবর্তে random.shuffle(b)এবং তারপর print(b)


44
#!/usr/bin/python3

import random

s=list(range(5))
random.shuffle(s) # << shuffle before print or assignment
print(s)

# print: [2, 4, 1, 3, 0]

31

আপনি যদি ইতিমধ্যে নিম্পি ব্যবহার করেন (বৈজ্ঞানিক এবং আর্থিক অ্যাপ্লিকেশনগুলির জন্য খুব জনপ্রিয়) আপনি নিজেকে একটি আমদানি সংরক্ষণ করতে পারেন।

import numpy as np    
np.random.shuffle(b)
print(b)

http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html


এই উত্তর সম্পর্কে আমি যা পছন্দ করি তা হ'ল আমি এলোমেলোভাবে এলোমেলো বীজকে নিয়ন্ত্রণ করতে পারি। আমি বাজি ধরেছি এলোমেলো মডিউলে এটি করার একটি উপায় আছে তবে এটি এখনই আমার কাছে সুস্পষ্ট নয় ... যার অর্থ আমাকে আরও পড়তে হবে।
ভ্যানব্যান্টাম

25
>>> import random
>>> a = ['hi','world','cat','dog']
>>> random.shuffle(a,random.random)
>>> a
['hi', 'cat', 'dog', 'world']

এটা আমার জন্য ভালই কাজ করে। এলোমেলো পদ্ধতি নির্ধারণের বিষয়টি নিশ্চিত করুন।


এখনও আমার পক্ষে কাজ করে না, সম্পাদিত প্রশ্নে আমার উদাহরণ কোডটি দেখুন।
উদ্বিগ্ন

4
দ্বিতীয় প্যারামিটারটি এলোমেলোভাবে .random এ ডিফল্ট। এটি ছেড়ে দেওয়া পুরোপুরি নিরাপদ।
cbare

3
@ অ্যালভাস র্যান্ডম.শ্যাফল (ক) কোনও জিনিস ফেরত দেয় না এটি কোনও কিছুই ফেরায় না। সুতরাং আপনাকে একটি নোট রিটার্ন মানটি পরীক্ষা করতে হবে।
sonus21

15

আপনার যদি একাধিক তালিকাগুলি থাকে তবে আপনি প্রথমে অনুমতিটি সংজ্ঞায়িত করতে (প্রথমে তালিকাটি পরিবর্তন করতে / তালিকাতে আইটেমগুলিকে পুনরায় সাজিয়ে তুলতে পারেন) এবং তারপরে সমস্ত তালিকায় এটি প্রয়োগ করতে পারেন:

import random

perm = list(range(len(list_one)))
random.shuffle(perm)
list_one = [list_one[index] for index in perm]
list_two = [list_two[index] for index in perm]

নোংরা / স্কিপি

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

import numpy as np

perm = np.random.permutation(len(list_one))
list_one = list_one[perm]
list_two = list_two[perm]

mpu

আমি ছোট ইউটিলিটি প্যাকেজ তৈরি করেছি mpuযা এতে consistent_shuffleফাংশন রয়েছে:

import mpu

# Necessary if you want consistent results
import random
random.seed(8)

# Define example lists
list_one = [1,2,3]
list_two = ['a', 'b', 'c']

# Call the function
list_one, list_two = mpu.consistent_shuffle(list_one, list_two)

নোট যে mpu.consistent_shuffleআর্গুমেন্ট একটি স্বেচ্ছাসেবী সংখ্যা লাগে। সুতরাং আপনি এটির সাথে তিন বা ততোধিক তালিকাগুলিও বদলাতে পারেন।


10
from random import random
my_list = range(10)
shuffled_list = sorted(my_list, key=lambda x: random())

এই বিকল্পটি এমন কিছু অ্যাপ্লিকেশনগুলির জন্য দরকারী হতে পারে যেখানে আপনি ক্রম ক্রমটি অদলবদল করতে চান।


এছাড়াও, মনে রাখবেন যে আপনাকে ধন্যবাদ sorted, এটি একটি কার্যকরী রদবদল (যদি আপনি সেই ধরণের জিনিসটিতে থাকেন)।
ইনাইমাঠি

1
টিমসোর্টের স্থায়িত্বের কারণে এটি এলোমেলোভাবে মানগুলি বিতরণ করে না। (একই কী সহ মানগুলি তাদের মূল ক্রমে রেখে গেছে)) সম্পাদনা: আমি মনে করি .৪-বিট ফ্লোটের সাথে সংঘর্ষের ঝুঁকিটি বেশ ন্যূনতম হওয়ায় এটি বিবেচ্য নয়।
মতিন উলহাক

10

কিছু ক্ষেত্রে নমুনি অ্যারে ব্যবহার করার সময় অ্যারেটিতে random.shuffleতৈরি করা সদৃশ ডেটা ব্যবহার করা হয় ।

একটি বিকল্প ব্যবহার করা হয় numpy.random.shuffle। আপনি যদি ইতিমধ্যে নিম্পের সাথে কাজ করছেন তবে এটি জেনেরিকের চেয়ে পছন্দসই পদ্ধতি random.shuffle

numpy.random.shuffle

উদাহরণ

>>> import numpy as np
>>> import random

ব্যবহার random.shuffle:

>>> foo = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> foo

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])


>>> random.shuffle(foo)
>>> foo

array([[1, 2, 3],
       [1, 2, 3],
       [4, 5, 6]])

ব্যবহার numpy.random.shuffle:

>>> foo = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> foo

array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])


>>> np.random.shuffle(foo)
>>> foo

array([[1, 2, 3],
       [7, 8, 9],
       [4, 5, 6]])

1
এছাড়াও, numpy.random.permutationআগ্রহের বিষয় হতে পারে: স্ট্যাকওভারফ্লো
গর্ডন বিন

এলোমেলো.স্যাফল ব্যবহার করার সময় আপনার কাছে অ্যারেতে সদৃশ ডেটা তৈরি হওয়ার উদাহরণ রয়েছে?
নুরেটিন

হ্যাঁ - এটি আমার উত্তরের অন্তর্ভুক্ত। "উদাহরণ" শিরোনামে বিভাগটি দেখুন। ;)
গর্ডন বিন 20

কিছু নয়, আমি তিনটি উপাদান দেখেছি এবং ভেবেছিলাম এটি একই it চমৎকার সন্ধান করুন
নুরেটিন

1
random.shuffleডকুমেন্টেশনে চিৎকার করতে হবে নাম্পার অ্যারেগুলি ব্যবহার করবেন না
শীতকালীন আলো

10

ওয়ান-লাইনারগুলির জন্য, random.sample(list_to_be_shuffled, length_of_the_list)উদাহরণ সহ ব্যবহার করুন :

import random
random.sample(list(range(10)), 10)

ফলাফল: [২, ৯, 7, ৮, ৩, ০, ৪, ১, 6, ৫]


6

'মুদ্রণ ফ্যানক (ফু)' 'ফু'-র সাথে ডাকা হলে' ফানক 'এর রিটার্ন মানটি প্রিন্ট করবে। 'বদলানো' এর রিটার্ন টাইপ হিসাবে কোনওটি নেই, কারণ তালিকাটি জায়গায় পরিবর্তিত হবে, সুতরাং এটি কিছুই প্রিন্ট করে না। কার্যসংক্রান্ত:

# shuffle the list in place 
random.shuffle(b)

# print it
print(b)

আপনি যদি ক্রিয়ামূলক প্রোগ্রামিং শৈলীতে আরও বেশি থাকেন তবে আপনি নীচের মোড়কের ফাংশনটি তৈরি করতে চাইতে পারেন:

def myshuffle(ls):
    random.shuffle(ls)
    return ls

2
যেহেতু এটি তালিকার একটি রেফারেন্স পাস করে, মূলটি পরিবর্তিত হয়। ডিপকপি
shivram.ss

@ shivram.ss এই ক্ষেত্রে, আপনি random.sample(ls, len(ls))যদি সত্যিই সেই পথে যেতে চান তবে আপনি এমন কিছু চাইবেন ।
আর্দা Xi

4

একটি shuffled( sortবনাম একই অর্থে sorted) নামক একটি ফাংশন সংজ্ঞায়িত করতে পারে

def shuffled(x):
    import random
    y = x[:]
    random.shuffle(y)
    return y

x = shuffled([1, 2, 3, 4])
print x

3
import random

class a:
    foo = "bar"

a1 = a()
a2 = a()
a3 = a()
a4 = a()
b = [a1,a2,a3,a4]

random.shuffle(b)
print(b)

shuffle জায়গায় আছে, সুতরাং ফলাফল মুদ্রণ করবেন না, যা হয় None, কিন্তু তালিকা।


1

আপনি এটির জন্য যেতে পারেন:

>>> A = ['r','a','n','d','o','m']
>>> B = [1,2,3,4,5,6]
>>> import random
>>> random.sample(A+B, len(A+B))
[3, 'r', 4, 'n', 6, 5, 'm', 2, 1, 'a', 'o', 'd']

আপনি যদি দুটি তালিকায় ফিরে যেতে চান তবে আপনি এই দীর্ঘ তালিকাটিকে দুটি ভাগে ভাগ করে নিন।


1

আপনি এমন একটি ফাংশন তৈরি করতে পারেন যা প্যারামিটার হিসাবে একটি তালিকা নেয় এবং তালিকার একটি পরিবর্তিত সংস্করণ প্রদান করে:

from random import *

def listshuffler(inputlist):
    for i in range(len(inputlist)):
        swap = randint(0,len(inputlist)-1)
        temp = inputlist[swap]
        inputlist[swap] = inputlist[i]
        inputlist[i] = temp
    return inputlist

1
""" to shuffle random, set random= True """

def shuffle(x,random=False):
     shuffled = []
     ma = x
     if random == True:
         rando = [ma[i] for i in np.random.randint(0,len(ma),len(ma))]
         return rando
     if random == False:
          for i in range(len(ma)):
          ave = len(ma)//3
          if i < ave:
             shuffled.append(ma[i+ave])
          else:
             shuffled.append(ma[i-ave])    
     return shuffled

একটি ছোট ভূমিকা বা ব্যাখ্যা সহায়ক হবে?
kacase

ফাংশন বদলানো ক্রিয়াকলাপের জন্য সহায়ক, কল্পনা করুন যে আপনাকে তিনবারের জন্য সংখ্যার একটি তালিকা পরিবর্তন করতে হবে এবং তিনবারের জন্য আপনাকে এলোমেলোভাবে বদলাতে হবে তখন কেবল এলোমেলো যুক্তিটি সত্যের দিকে ঘুরিয়ে দিন যদি আপনার এলোমেলো প্রয়োজন হয় না এবং আপনি চান সংরক্ষণ করার জন্য একই শ্যাফলিং ক্রমটি কোনও পরিবর্তন করবেন না, কেবল কোড চালান।
জোশ আনিস

যেহেতু কোনও ব্যবহারের ঘটনা নেই যেখানে এই ফাংশনটির কলকারী রানটাইম স্থির করে সিদ্ধান্ত নেবেন যে তিনি এলোমেলো বা নন-র্যান্ডম পরিবর্তন করতে চান, এই ফাংশনটি দুটি ভাগে বিভক্ত হওয়া উচিত।
টুলফোজার

নন-এলোমেলো শ্যাফেলটি কী করার কথা রয়েছে তার কোনও বিবরণ নেই। (কোনও স্পর্শকালে এটি কোনও উত্তর নয়, সুতরাং প্রশ্ন, সুতরাং এটি স্ট্যাক ওভারফ্লোয়ের উদ্দেশ্যটি কার্যকর করে না))
টুলফোজার

1

আপনি হয় পরিবর্তন বা নমুনা ব্যবহার করতে পারেন। উভয় এলোমেলো মডিউল থেকে আসা।

import random
def shuffle(arr1):
    n=len(arr1)
    b=random.sample(arr1,n)
    return b

অথবা

import random
def shuffle(arr1):
    random.shuffle(arr1)
    return arr1

0

নিশ্চিত হয়ে নিন যে আপনি আপনার উত্স ফাইলটি এলোমেলো.পিপি নামকরণ করছেন না এবং আপনার ওয়ার্কিং ডিরেক্টরিতে র্যান্ডম.পিসিসি নামে একটি ফাইল নেই .. আপনার প্রোগ্রামটি পাইথন র্যান্ডম মডিউলের পরিবর্তে আপনার স্থানীয় র্যান্ডম.পি ফাইলটি আমদানি করার চেষ্টা করতে পারে cause ।


0
def shuffle(_list):
    if not _list == []:
        import random
        list2 = []
        while _list != []:
            card = random.choice(_list)
            _list.remove(card)
            list2.append(card)
        while list2 != []:
            card1 = list2[0]
            list2.remove(card1)
            _list.append(card1)
        return _list

আপনি যদি এলোমেলো মডিউলটি ব্যবহার না করতে চান তবে এই ফাংশনটি আপনাকে সহায়তা করতে পারে
পোগ্রামিস্ট

এই সমাধানটি কেবল ভার্বোস নয়, অদক্ষ (রানটাইম তালিকার আকারের বর্গক্ষেত্রের সমানুপাতিক)।
টুলফোজার

দ্বিতীয় লুপটি প্রতিস্থাপিত হতে পারে _list.extend(list2), যা আরও সংক্ষিপ্ত এবং আরও কার্যকর।
টুলফোজার

একটি পাইথন ফাংশন যা কোনও পরামিতি সংশোধন করে তার ফলাফল কখনই ফিরে আসে না। এটি কেবল একটি কনভেনশন, তবে একটি দরকারী একটি: লোকেরা প্রায়শই তাদের ডাকা সমস্ত ফাংশনগুলির বাস্তবায়ন দেখার সময়ের অভাব হয়, সুতরাং যে কেউ আপনার ফাংশনটির নামটি দেখেন এবং এর ফলস্বরূপ যে কেউ এই কার্যটি দেখে খুব অবাক হবেন এর প্যারামিটার আপডেট করুন।
টুলফোজার


-1

বদলানোর প্রক্রিয়াটি "প্রতিস্থাপন সহ" , সুতরাং প্রতিটি আইটেমের উপস্থিতি পরিবর্তন হতে পারে! অন্তত যখন আপনার তালিকার আইটেমগুলিও তালিকাভুক্ত থাকে।

যেমন,

ml = [[0], [1]] * 10

পর

random.shuffle(ml)

[0] এর সংখ্যা 9 বা 8 হতে পারে তবে 10 নয়।


-1

পরিকল্পনা: ভারী উত্তোলনের জন্য কোনও লাইব্রেরির উপর নির্ভর না করে এলোমেলো লিখুন। উদাহরণ: তালিকা থেকে শুরু করে এলিমেন্ট 0 দিয়ে শুরু করুন; এটির জন্য একটি নতুন এলোমেলো অবস্থান সন্ধান করুন, 6 বলুন, 0 এর মান 6 এবং 6 এর মান 0 তে রাখুন উপাদান 1 এ যান এবং এই প্রক্রিয়াটি পুনরাবৃত্তি করুন, এবং আরও অন্যান্য তালিকার মাধ্যমে

import random
iteration = random.randint(2, 100)
temp_var = 0
while iteration > 0:

    for i in range(1, len(my_list)): # have to use range with len()
        for j in range(1, len(my_list) - i):
            # Using temp_var as my place holder so I don't lose values
            temp_var = my_list[i]
            my_list[i] = my_list[j]
            my_list[j] = temp_var

        iteration -= 1

আপনি my_list[i], my_list[j] = my_list[j], my_list[i]
অজগরটিতে

-2

এটা ঠিক কাজ করে। তালিকার অবজেক্ট হিসাবে ফাংশন সহ আমি এখানে এটি চেষ্টা করছি:

    from random import shuffle

    def foo1():
        print "foo1",

    def foo2():
        print "foo2",

    def foo3():
        print "foo3",

    A=[foo1,foo2,foo3]

    for x in A:
        x()

    print "\r"

    shuffle(A)
    for y in A:
        y()

এটি মুদ্রণ করে: foo1 foo2 foo3 foo2 foo3 foo1 (শেষ সারিতে foos একটি এলোমেলো ক্রম আছে)

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