পাইথনে কোনও তালিকা ঘোরানোর কার্যকর উপায়


263

পাইথনে তালিকা ঘোরানোর সবচেয়ে কার্যকরী উপায় কী? এই মুহূর্তে আমার কাছে এরকম কিছু রয়েছে:

>>> def rotate(l, n):
...     return l[n:] + l[:n]
... 
>>> l = [1,2,3,4]
>>> rotate(l,1)
[2, 3, 4, 1]
>>> rotate(l,2)
[3, 4, 1, 2]
>>> rotate(l,0)
[1, 2, 3, 4]
>>> rotate(l,-1)
[4, 1, 2, 3]

একটি ভাল উপায় আছে কি?


12
অন্যান্য ভাষাগুলি (পার্ল, রুবি) শব্দটি ব্যবহার করায় এটি সত্যই পরিবর্তন হয় না। এটি ঘোরানো। প্রশ্নটি কি সেই অনুযায়ী আপডেট করা উচিত?
ভিনসেন্ট ফোরমন্ড

@ ডাঃহিল আমি আপনার আসল সমাধানটি সত্যিই পছন্দ করি কারণ এটি মিউটেশনগুলির পরিচয় দেয় না
জুনাচিতো


2
আমি মনে করি rotateসঠিক শব্দ, না shift
কোডফোরস্টার

2
বাস্তব সঠিক উত্তর, আপনি কখনই প্রথম স্থানে তালিকা আবর্তিত করা যায়। আপনার তালিকার যৌক্তিক স্থানে একটি "পয়েন্টার" ভেরিয়েবল তৈরি করুন যেখানে আপনি "মাথা" বা "লেজ" বানাতে চান এবং তালিকার কোনও আইটেম স্থানান্তরিত না করে সেই পরিবর্তনশীলটি পরিবর্তন করুন। আপনার পয়েন্টারটিকে সূচনার শুরু এবং শেষের দিকে "মোড়ানোর" দক্ষ উপায়ের জন্য "মডুলো" অপারেটর% সন্ধান করুন।
সিডি করুন

উত্তর:


280

collections.dequeদুটি প্রান্তে টানতে এবং ধাক্কা দেওয়ার জন্য অনুকূলিত। এমনকি তাদের একটি উত্সর্গীকৃত rotate()পদ্ধতি রয়েছে।

from collections import deque
items = deque([1, 2])
items.append(3)        # deque == [1, 2, 3]
items.rotate(1)        # The deque is now: [3, 1, 2]
items.rotate(-1)       # Returns deque to original state: [1, 2, 3]
item = items.popleft() # deque == [2, 3]

8
ভবিষ্যতের পাঠকদের জন্য: wiki.python.org/moin/TimeComplexitycollections.deque rotate() অনুসারে কাটা কাটা
জিওফ

2
তবে সচেতন থাকুন, ব্যবহারের deque.rotateজন্য dequeপ্রথমে কোনও বস্তুর জন্য ধরণের রূপান্তর প্রয়োজন যা এর চেয়ে ধীর l.append(l.pop(0))। সুতরাং আপনার যদি শুরু করার মতো কোনও উপযুক্ত বস্তু থাকে তবে নিশ্চিত যে এটি দ্রুত। অন্যথায়, ব্যবহার করুন l.append(l.pop(0))
পূরেল

8
বিস্তারিতভাবে বলতে গেলে, deque.rotateও (কে) তবে তালিকা থেকে ডেকিতে রূপান্তরটি টাইপ করুন ও (এন) । সুতরাং আপনি যদি একটি তালিকা দিয়ে শুরু করেন, deque.rotate ব্যবহার করে হ'ল O (n) + O (k) = O (n)। l.append(l.pop(0))অন্যদিকে ও (1)।
পূর্ণাল

3
@ পারল, সামনের আইটেমটি পপিং করা হ'ল ও (এন)। Wiki.python.org/moin/TimeComplexity এ এটি ও (কে) হিসাবে তালিকাভুক্ত হয়েছে এবং কে পপড আইটেমের নীচে তালিকার উপাদানগুলির সংখ্যা, কারণ ডেটা স্ট্রাকচার নীচের সমস্ত উপাদানকে তালিকার সামনের দিকে স্থানান্তরিত করে। এই কারণে শুধুমাত্র শেষ উপাদানটি ও (1) সময়ে পপ করা যায়।
বায়ার

88

শুধু ব্যবহার সম্পর্কে কি pop(0)?

list.pop([i])

তালিকার প্রদত্ত অবস্থানে আইটেমটি সরান এবং এটি ফিরিয়ে দিন। যদি কোনও সূচক নির্দিষ্ট না করা থাকে, a.pop()তবে তালিকার শেষ আইটেমটি সরিয়ে দেয় এবং ফেরত দেয়। ( iপদ্ধতিতে স্বাক্ষরের চারপাশের বর্গাকার বন্ধনীগুলি বোঝায় যে প্যারামিটারটি alচ্ছিক, আপনি যে অবস্থানে স্কোয়ার বন্ধনী টাইপ করবেন না You আপনি পাইথন লাইব্রেরি রেফারেন্সে ঘন ঘন এই চিহ্নটি দেখতে পাবেন see)


16
তবে তালিকার প্রতিটি উপাদান অপসারণের জন্য ও (কে) ব্যয় করতে হবে না যেখানে কে অবশিষ্ট উপাদানগুলির সংখ্যা। সুতরাং মোট সময় হবে ও (এন ^ 2) wiki.python.org/moin/TimeComplexity
প্রমোদ

5
এটি আসলে প্রশ্নের উত্তর দেয় না। প্রশ্নটি আইটেমগুলি ক্রমে ফিরিয়ে আনার বিষয়ে নয়, বরং একটি ভিন্ন তালিকায় থাকা একটি নতুন তালিকা তৈরির বিষয়ে।
ব্যবহারকারী 650261

5
না, পপ ব্যবহার করে প্রশ্নের উত্তর হবে l.append(l.pop(0)। যা আমি ভুল না হলে ও (1)।
পূর্ণে

4
list.pop অভ্যন্তরীণভাবে list_ass_slice কল করে যা খুব দ্রুত সমস্ত আইটেম সরিয়ে নিতে মেমোভ ব্যবহার করে তবে এটি ও (এন)। দেখুন github.com/python/cpython/blob/master/Objects/listobject.c এবং wiki.python.org/moin/TimeComplexity । অবিরাম সময়ে অজগর তালিকা থেকে সরিয়ে ফেলা যায় এমন একমাত্র আইটেমটি সর্বশেষ।
DRayX

2
Downvoted। ডকস.পিথোন.আর. / ৩ / টিউটোরিয়াল/… থেকে একটি সারি হিসাবে একটি তালিকা ব্যবহার করাও সম্ভব, যেখানে যুক্ত হওয়া প্রথম উপাদানটি হ'ল প্রথম উপাদান পুনরুদ্ধার করা ("প্রথম-ইন, প্রথম-আউট"); তবে তালিকাগুলি এই উদ্দেশ্যে কার্যকর নয়। তালিকার শেষে থেকে সংযোজন এবং পপগুলি দ্রুত, তালিকার শুরু থেকে সন্নিবেশ বা পপগুলি করা ধীর গতিতে (কারণ অন্যান্য উপাদানগুলির মধ্যে একটি দ্বারা স্থানান্তরিত করতে হবে)।
সান্তাএক্সএল

59

নম্পি rollকমান্ডটি ব্যবহার করে এটি করতে পারে :

>>> import numpy
>>> a=numpy.arange(1,10) #Generate some data
>>> numpy.roll(a,1)
array([9, 1, 2, 3, 4, 5, 6, 7, 8])
>>> numpy.roll(a,-1)
array([2, 3, 4, 5, 6, 7, 8, 9, 1])
>>> numpy.roll(a,5)
array([5, 6, 7, 8, 9, 1, 2, 3, 4])
>>> numpy.roll(a,9)
array([1, 2, 3, 4, 5, 6, 7, 8, 9])

1
এসও সম্পর্কে আমি যা ভালবাসি তা হ'ল উত্তর ফিডের নীচে আপনি এর মতো কিছু দুর্দান্ত নতুন ধন খুঁজে পেতে পারেন :)
noamgot

এটি, যখন আমি এটি পরীক্ষা করেছি তখন খুব ধীর
পিটার হ্যারিসন

@ পিটারহরিসন: যেহেতু আপনি পরীক্ষার বিবরণ সরবরাহ করেন না আপনি কী বোঝাতে চাইছেন তা জানা শক্ত। এই উত্তরটি পুরো পরীক্ষার বিশদ এবং একটি সময় তুলনা সরবরাহ করে।
রিচার্ড

33

এটি যখন আপনি এটি করতে চান তখন তার উপর নির্ভর করে:

>>> shift([1,2,3], 14)

আপনি নিজের পরিবর্তন করতে পারেন:

def shift(seq, n):
    return seq[n:]+seq[:n]

প্রতি:

def shift(seq, n):
    n = n % len(seq)
    return seq[n:] + seq[:n]

5
এনবি: এটি খালি তালিকার জন্য ক্রাশ হবে।
meawoppl

n = n% লেন (সেক) রিটার্ন = সেক [-n:] + সিক [: - n]
ইউজার 3303020

আপনি ব্যাখ্যা করতে পারেন কেন এন = এন% লেন (সেক)?
এ্যারিসস

16

সবচেয়ে সহজ উপায় যা আমি ভাবতে পারি:

a.append(a.pop(0))

3
এটি তালিকার দ্রুততম উপায়। collections.dequeদ্রুত তবে তবে একক পুনরাবৃত্তির তালিকার দৈর্ঘ্যের বেশিরভাগ সাধারণ ক্ষেত্রে বা একাধিক পুনরাবৃত্তির যে কোনও ক্ষেত্রে a.append(a.pop(0))
ডেকিতে

@RunDOSrun এই প্রশ্নের সঠিক উত্তর যা দুঃখজনকভাবে ডুপ্লিকেট হিসাবে বন্ধ রয়েছে। আপনি আবার খুলতে চাইবেন?
ওল্ফ

15

আপনি যদি পৃথক ডেটা কাঠামো নির্মাণের পরিবর্তে এই উপাদানগুলির সেটগুলিতে কেবল পুনরাবৃত্তি করতে চান, তবে জেনারেটর এক্সপ্রেশনটি নির্মাণের জন্য পুনরুক্তিগুলি ব্যবহার করে বিবেচনা করুন:

def shift(l,n):
    return itertools.islice(itertools.cycle(l),n,n+len(l))

>>> list(shift([1,2,3],1))
[2, 3, 1]

11

আপনি যদি তালিকায় স্থান পরিবর্তন করতে চান (এটি পরিবর্তন করে), অথবা আপনি যদি ফাংশনটি কোনও নতুন তালিকা ফিরিয়ে দিতে চান তবে এটিও নির্ভর করে। কারণ, আমার পরীক্ষাগুলি অনুসারে, এরকম কিছু আপনার প্রয়োগের চেয়ে কমপক্ষে বিশগুণ দ্রুত যা দুটি তালিকা যুক্ত করে:

def shiftInPlace(l, n):
    n = n % len(l)
    head = l[:n]
    l[:n] = []
    l.extend(head)
    return l

প্রকৃতপক্ষে, l = l[:]পাস করা তালিকার একটি অনুলিপি পরিচালনা করতে এমনকি তার শীর্ষে একটি যুক্ত করা এখনও দ্বিগুণ দ্রুত is

Http://gist.github.com/288272 এ কিছু সময় সহ বিভিন্ন বাস্তবায়ন


3
পরিবর্তে l[:n] = []আমি জন্য যেতে হবে del l[:n]। শুধু একটি বিকল্প।
tzot

1
ওহ, হ্যাঁ, ভাল পুরানো দেল। আমি প্রায়শই ডেল সম্পর্কে ভুলে যাই; তালিকা অপারেশন যে একটি বিবৃতি, একটি পদ্ধতি নয়। পাই 3 কে কি সেই দৌরাত্মা বদলেছে, না আমরা এখনও পেয়েছি?
কেটর্ন

2
@keturn: পাই 3- delতে এখনও একটি বিবৃতি। তবে x.__delitem__(y) <==> del x[y], যদি আপনি পদ্ধতিগুলি ব্যবহার করতে পছন্দ করেন তবে l.__delitem__(slice(n))এটিও সমান এবং 2 এবং 3 উভয় ক্ষেত্রেই কাজ করে
মার্টিনিউ

9

সময় সম্পর্কে কিছু নোট:

যদি আপনি একটি তালিকা দিয়ে শুরু করেন তবে আপনি l.append(l.pop(0))ব্যবহার করতে পারেন এমন দ্রুত পদ্ধতি। এটি একা সময় জটিলতার সাথে দেখানো যেতে পারে:

  • deque.rotate হল ও (কে) (কে = উপাদানগুলির সংখ্যা)
  • যোগ্য রূপান্তরকরণের তালিকাটি হ'ল ও (এন)
  • list.append এবং list.pop উভয়ই (1)

সুতরাং আপনি যদি কোনও dequeজিনিস দিয়ে শুরু করে থাকেন তবে আপনি deque.rotate()ও (কে) এর ব্যয় করতে পারেন । তবে, যদি সূচনা পয়েন্টটি একটি তালিকা হয় তবে ব্যবহারের সময় জটিলতা deque.rotate()হ'ল হে (এন)। l.append(l.pop(0)ও (1) এ দ্রুত

কেবলমাত্র উদাহরণের জন্য, 1M পুনরাবৃত্তির উপর কয়েকটি নমুনার সময় এখানে দেওয়া হয়েছে:

ধরণের রূপান্তর প্রয়োজন এমন পদ্ধতিগুলি:

  • deque.rotateডেক অবজেক্ট সহ: 0.12380790710449219 সেকেন্ড (দ্রুততম)
  • deque.rotateধরণের রূপান্তর সহ: 6.853878974914551 সেকেন্ড
  • np.rollএনপ্যারে সহ: 6.0491721630096436 সেকেন্ড
  • np.rollধরণের রূপান্তর সহ: 27.558452129364014 সেকেন্ড

তালিকা এখানে তালিকাভুক্ত:

  • l.append(l.pop(0)): 0.32483696937561035 সেকেন্ড (দ্রুততম)
  • " shiftInPlace": 4.819645881652832 সেকেন্ড
  • ...

ব্যবহৃত টাইমিং কোডটি নীচে।


collections.deque

তালিকাগুলি থেকে ডিয়াক তৈরি করা হ'ল ও (এন):

from collections import deque
import big_o

def create_deque_from_list(l):
     return deque(l)

best, others = big_o.big_o(create_deque_from_list, lambda n: big_o.datagen.integers(n, -100, 100))
print best

# --> Linear: time = -2.6E-05 + 1.8E-08*n

আপনার যদি ডিউক অবজেক্ট তৈরি করা দরকার:

1 এম পুনরাবৃত্তি @ 6.853878974914551 সেকেন্ড

setup_deque_rotate_with_create_deque = """
from collections import deque
import random
l = [random.random() for i in range(1000)]
"""

test_deque_rotate_with_create_deque = """
dl = deque(l)
dl.rotate(-1)
"""
timeit.timeit(test_deque_rotate_with_create_deque, setup_deque_rotate_with_create_deque)

আপনার যদি ইতিমধ্যে উপযুক্ত বস্তু থাকে:

1 এম পুনরাবৃত্তি @ 0.12380790710449219 সেকেন্ড

setup_deque_rotate_alone = """
from collections import deque
import random
l = [random.random() for i in range(1000)]
dl = deque(l)
"""

test_deque_rotate_alone= """
dl.rotate(-1)
"""
timeit.timeit(test_deque_rotate_alone, setup_deque_rotate_alone)

np.roll

আপনার যদি nparrays তৈরি করা প্রয়োজন

1 এম পুনরাবৃত্তি @ 27.558452129364014 সেকেন্ড

setup_np_roll_with_create_npa = """
import numpy as np
import random
l = [random.random() for i in range(1000)]
"""

test_np_roll_with_create_npa = """
np.roll(l,-1) # implicit conversion of l to np.nparray
"""

আপনার যদি ইতিমধ্যে এনপ্যারে থাকে:

1 এম পুনরাবৃত্তি @ 6.0491721630096436 সেকেন্ড

setup_np_roll_alone = """
import numpy as np
import random
l = [random.random() for i in range(1000)]
npa = np.array(l)
"""

test_roll_alone = """
np.roll(npa,-1)
"""
timeit.timeit(test_roll_alone, setup_np_roll_alone)

"স্থান পরিবর্তন"

কোনও ধরণের রূপান্তর প্রয়োজন

1 এম পুনরাবৃত্তি @ 4.819645881652832 সেকেন্ড

setup_shift_in_place="""
import random
l = [random.random() for i in range(1000)]
def shiftInPlace(l, n):
    n = n % len(l)
    head = l[:n]
    l[:n] = []
    l.extend(head)
    return l
"""

test_shift_in_place="""
shiftInPlace(l,-1)
"""

timeit.timeit(test_shift_in_place, setup_shift_in_place)

l.append (l.pop (0))

কোনও ধরণের রূপান্তর প্রয়োজন

1 এম পুনরাবৃত্তি @ 0.32483696937561035

setup_append_pop="""
import random
l = [random.random() for i in range(1000)]
"""

test_append_pop="""
l.append(l.pop(0))
"""
timeit.timeit(test_append_pop, setup_append_pop)

2
যখন list.pop () একটি ধ্রুবক সময় অপারেশন, list.pop (0) হয় না । এটি দৈর্ঘ্যের সাথে তালিকার দৈর্ঘ্যের ক্ষেত্রে চলে। আপনার সময় নির্ধারণের সেটআপটি পরিবর্তন করে আপনি এটি পরীক্ষা করতে পারেন:l = [random.random() for i in range(100000)]
ইমু

1
list.pop একটি ধ্রুবক সময় ক্রিয়াকলাপ নয়। list.pop O (k) সময়ে চলে যেখানে k অপসারণ উপাদানগুলির অতীতের সংখ্যা, সুতরাং list.pop (0) হ'ল (এন)। অভ্যন্তরীণভাবে, list.pop list_ass_slice ব্যবহার করে যা মাইমোভ ব্যবহার করে আইটেমগুলিকে পাইথনের চেয়ে দ্রুত গতিতে চালিত করতে পারে তবে দীর্ঘ তালিকাগুলির জন্য এটি এখনও খুব সময়সাপেক্ষ। দেখুন github.com/python/cpython/blob/master/Objects/listobject.c এবং wiki.python.org/moin/TimeComplexity
DRayX

সময় দেওয়ার জন্য ধন্যবাদ (এবং মন্তব্যগুলি @ ইমু)। সুতরাং আমরা কি বলতে পারি যে l.append(l.pop(0))সংক্ষিপ্ত তালিকাগুলি (প্রায় 7 টি উপাদান) একটি করে স্থানান্তরিত করার জন্য সবচেয়ে ভাল পারফর্ম করা হচ্ছে?
ওল্ফ

আবারও l.append(l.pop(0))উত্তর হিসাবে: এই প্রশ্নটি নকল হিসাবে বন্ধ রয়েছে। আপনি আবার খুলতে চাইবেন?
ওল্ফ

8

আমি এটিতে আগ্রহীও হয়েছি এবং প্রস্তাবিত সমাধানগুলির কয়েকটিকে পারফ্লোট (আমার একটি ছোট প্রকল্প) এর সাথে তুলনা করি ।

এটা দেখা যাচ্ছে যে

for _ in range(n):
    data.append(data.pop(0))

হয় দ্বারা পর্যন্ত ছোট বদল আনতে সবচেয়ে দ্রুত পদ্ধতি n

বৃহত্তর জন্য n,

data[n:] + data[:n]

খারাপ না

মূলত, পার্ফ্ল্লট বড় অ্যারে বাড়ানোর জন্য শিফট সম্পাদন করে এবং সময়টি পরিমাপ করে। ফলাফল এখানে:

shift = 1:

এখানে চিত্র বর্ণনা লিখুন

shift = 100:

এখানে চিত্র বর্ণনা লিখুন


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

import numpy
import perfplot
import collections


shift = 100


def list_append(data):
    return data[shift:] + data[:shift]


def shift_concatenate(data):
    return numpy.concatenate([data[shift:], data[:shift]])


def roll(data):
    return numpy.roll(data, -shift)


def collections_deque(data):
    items = collections.deque(data)
    items.rotate(-shift)
    return items


def pop_append(data):
    for _ in range(shift):
        data.append(data.pop(0))
    return data


perfplot.save(
    "shift100.png",
    setup=lambda n: numpy.random.rand(n).tolist(),
    kernels=[list_append, roll, shift_concatenate, collections_deque, pop_append],
    n_range=[2 ** k for k in range(7, 20)],
    logx=True,
    logy=True,
    xlabel="len(data)",
)

আপনি তৈরি দুর্দান্ত সরঞ্জাম। বিষয়ে l.append(l.pop(0))একটি উত্তর হিসাবে: এই প্রশ্নের সদৃশ হিসাবে বন্ধ করা হয়। আপনি আবার খুলতে চাইবেন?
ওল্ফ

4

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

সমস্যাটি হ'ল একটি তালিকার শিফটের কার্যক্ষমতা হ'ল ও (এন), যা যথেষ্ট পরিমাণে পর্যাপ্ত তালিকার জন্য গুরুত্বপূর্ণ হয়ে ওঠে।

একটি রিংবফারে স্থানান্তর করা কেবল হেডের অবস্থান আপডেট করে যা হে (1)


4

অপরিবর্তনীয় বাস্তবায়নের জন্য আপনি এরকম কিছু ব্যবহার করতে পারেন:

def shift(seq, n):
    shifted_seq = []
    for i in range(len(seq)):
        shifted_seq.append(seq[(i-n) % len(seq)])
    return shifted_seq

print shift([1, 2, 3, 4], 1)

3

দক্ষতা যদি আপনার লক্ষ্য হয়, (চক্র? মেমরি?) আপনি অ্যারে মডিউলটি দেখে ভাল হতে পারেন: http://docs.python.org/library/array.html

অ্যারেগুলির তালিকার ওভারহেড নেই।

যতক্ষণ না খাঁটি তালিকাগুলি যায়, আপনার কাছে যা আশা করা যায় তত ভাল।


3

আমি মনে করি আপনি এটি সন্ধান করছেন:

a.insert(0, x)

প্রশ্ন এবং আপনার উত্তরের মধ্যকার সম্পর্ক আমি দেখছি না। আপনি দয়া করে এটি ব্যাখ্যা করতে পারেন?
ওল্ফ

2

অন্য বিকল্প:

def move(arr, n):
    return [arr[(idx-n) % len(arr)] for idx,_ in enumerate(arr)]

1

আমি এই মূল্য মডেলটিকে রেফারেন্স হিসাবে নিই:

http://scripts.mit.edu/~6.006/fall07/wiki/index.php?title=Python_Cost_Model

তালিকাটি টুকরো টুকরো করার এবং দুটি উপ-তালিকাকে একত্রিত করার পদ্ধতিটি লিনিয়ার-টাইম ক্রিয়াকলাপ। আমি পপ ব্যবহার করার পরামর্শ দেব, যা একটি ধ্রুবক-সময় অপারেশন, যেমন:

def shift(list, n):
    for i in range(n)
        temp = list.pop()
        list.insert(0, temp)

2
আপডেট: এটিকে আরও ভাল রেফারেন্স হিসাবে গ্রহণ করুন: উইকি.পাইথন.আর.আমিন / টাইমকম্প্লেসিটি , collections.dequeueপপ এবং অ্যাপেন্ডেলফ্ট ব্যবহার করুন , যা উভয়ই ও (1) অপ্স। উপরের আমার প্রথম উত্তরে, সন্নিবেশটি হ'ল হে (এন)।
হার্ফজ

1
হওয়া উচিতcollections.deque
হার্ফজ

1

আমি জানি না এটি 'দক্ষ' কিনা, তবে এটি কাজ করে:

x = [1,2,3,4]
x.insert(0,x.pop())

সম্পাদনা: হ্যালো আবার, আমি এই সমাধানটি সবেমাত্র একটি বড় সমস্যা পেয়েছি! নিম্নলিখিত কোড বিবেচনা করুন:

class MyClass():
    def __init__(self):
        self.classlist = []

    def shift_classlist(self): # right-shift-operation
        self.classlist.insert(0, self.classlist.pop())

if __name__ == '__main__':
    otherlist = [1,2,3]
    x = MyClass()

    # this is where kind of a magic link is created...
    x.classlist = otherlist

    for ii in xrange(2): # just to do it 2 times
        print '\n\n\nbefore shift:'
        print '     x.classlist =', x.classlist
        print '     otherlist =', otherlist
        x.shift_classlist() 
        print 'after shift:'
        print '     x.classlist =', x.classlist
        print '     otherlist =', otherlist, '<-- SHOULD NOT HAVE BIN CHANGED!'

Shift_classlist () পদ্ধতিটি আমার x.insert (0, x.pop ()) - সলিউশন হিসাবে একই কোডটি কার্যকর করে, অন্যান্য তালিকা তালিক শ্রেণীর তালিকাভুক্ত is MyClass.classlist তালিকায় অন্য তালিকার বিষয়বস্তুগুলি পাস করার পরে, shift_classlist () নাম্বারে কল করা অন্য তালিকা তালিকাকেও পরিবর্তন করে:

কনসোল আউটপুট:

before shift:
     x.classlist = [1, 2, 3]
     otherlist = [1, 2, 3]
after shift:
     x.classlist = [3, 1, 2]
     otherlist = [3, 1, 2] <-- SHOULD NOT HAVE BIN CHANGED!



before shift:
     x.classlist = [3, 1, 2]
     otherlist = [3, 1, 2]
after shift:
     x.classlist = [2, 3, 1]
     otherlist = [2, 3, 1] <-- SHOULD NOT HAVE BIN CHANGED!

আমি পাইথন ২.7 ব্যবহার করি। আমি বুঝতে পারি না যে কোনও ত্রুটি আছে কি না তবে আমি মনে করি এটি সম্ভবত এখানে কিছু ভুল করেছিলাম।

আপনারা কেউ জানেন যে কেন এমন হয়?


2
এটি ঘটে কারণ x.classlist = otherlistতোলে x.classlistহিসাবে একই তথ্য যোগ otherlistএবং তারপর আপনি কল যখন x.shift_classlist()এটা mutates তালিকা এবং কারণ উভয় নামই একই তালিকা বস্তুর পড়ুন। উভয় নামই পরিবর্তিত বলে মনে হচ্ছে কারণ তারা একই বস্তুর জন্য কেবলমাত্র উপমা। x.classlist = otherlist[:]পরিবর্তে তালিকার একটি অনুলিপি ব্যবহার করুন ।
ড্যান ডি

আরে বাহ! আপনাকে অনেক ধন্যবাদ! আমি সত্যিই এটি জানতাম না এবং এটি জেনে রাখা ভাল! :)
wese3112

1

নিম্নলিখিত পদ্ধতিটি ধ্রুবক সহায়ক মেমরির সাথে স্থানে O (n) রয়েছে:

def rotate(arr, shift):
  pivot = shift % len(arr)
  dst = 0
  src = pivot
  while (dst != src):
    arr[dst], arr[src] = arr[src], arr[dst]
    dst += 1
    src += 1
    if src == len(arr):
      src = pivot
    elif dst == pivot:
      pivot = src

দ্রষ্টব্য যে অজগরটিতে, অন্যদের তুলনায় এই পদ্ধতিরটি মারাত্মকভাবে অদক্ষ as কারণ এটি কোনও অংশে দেশীয় প্রয়োগের সুবিধা নিতে পারে না।


ভাল, আসলে আপনি list.pop এবং list.append ব্যবহার করতে পারেন। আপনি যে 12 লাইনের ক্রিয়াটি ও (এন) লিখেছেন তা ভাষার দোষ নয়, যখন আপনি কেবল "l.append (l.pop (0))" লিখতে পারতেন যা ধ্রুবক সময়।
পুরাবল

l.append (l.pop (0)) হ'ল O (n) (l.pop (0) প্রতিটি উপাদানকে শিফট করতে হবে), আপনি যদি এম মানগুলি স্থানান্তর করতে চান তবে জটিলতাটি আসলে ও (এন * মি)। আমি যে অ্যালগরিদম সরবরাহ করেছি তার জটিলতা হ'ল ও (এন) শিফটের সংখ্যা নির্বিশেষে। অনুশীলনে, এটি ধীরে ধীরে কারণ সিটির পরিবর্তে পাইথন অপ্সে এতগুলি যুক্তি সম্পন্ন করা হয় (list.pop সি প্রয়োগ করা হয়, github.com/python/cpython/blob/master/Objects/listobject.c দেখুন )।
DRayX

1

আমি একই জিনিস আছে। উদাহরণস্বরূপ, দুটি দ্বারা স্থানান্তরিত ...

def Shift(*args):
    return args[len(args)-2:]+args[:len(args)-2]

1

আমি মনে করি আপনি সবচেয়ে দক্ষ উপায় পেয়েছেন

def shift(l,n):
    n = n % len(l)  
    return l[-U:] + l[:-U]

0

ব্যবহারের ক্ষেত্রে কী? প্রায়শই, আমাদের আসলে পুরোপুরি স্থানান্তরিত অ্যারের প্রয়োজন হয় না - আমাদের কেবল স্থানান্তরিত অ্যারেটিতে কয়েকটি মুখ্য উপাদান অ্যাক্সেস করতে হবে।

পাইথনের টুকরো পাওয়া রানটাইম ও (কে) যেখানে কে স্লাইস, তাই একটি কাটা ঘূর্ণনটি রানটাইম এন হয় de আমরা কি আরও ভাল করতে পারি?

অত্যন্ত বড় এমন একটি অ্যারের বিবেচনা করুন (আসুন বলি, এত বড় এটি কমিয়ে দেওয়ার জন্য গণনামূলকভাবে ধীর হবে)। বিকল্প সমাধানটি হ'ল মূল অ্যারেটি একা ছেড়ে চলে যাওয়া এবং কেবলমাত্র কোনও ধরণের পরিবর্তনের পরে আমাদের পছন্দসই সূচীতে থাকা আইটেমের সূচকটি গণনা করা।

স্থানান্তরিত উপাদানের অ্যাক্সেস এভাবে ও (1) হয়ে যায়।

def get_shifted_element(original_list, shift_to_left, index_in_shifted):
    # back calculate the original index by reversing the left shift
    idx_original = (index_in_shifted + shift_to_left) % len(original_list)
    return original_list[idx_original]

my_list = [1, 2, 3, 4, 5]

print get_shifted_element(my_list, 1, 2) ----> outputs 4

print get_shifted_element(my_list, -2, 3) -----> outputs 2 

0

নিম্নলিখিত ক্রিয়াকলাপের অনুলিপিগুলি কোনও টেম্পলিস্টে তালিকা প্রেরণ করে, যাতে পপ ফাংশনটি মূল তালিকাকে প্রভাবিত করে না:

def shift(lst, n, toreverse=False):
    templist = []
    for i in lst: templist.append(i)
    if toreverse:
        for i in range(n):  templist = [templist.pop()]+templist
    else:
        for i in range(n):  templist = templist+[templist.pop(0)]
    return templist

পরীক্ষামূলক:

lst = [1,2,3,4,5]
print("lst=", lst)
print("shift by 1:", shift(lst,1))
print("lst=", lst)
print("shift by 7:", shift(lst,7))
print("lst=", lst)
print("shift by 1 reverse:", shift(lst,1, True))
print("lst=", lst)
print("shift by 7 reverse:", shift(lst,7, True))
print("lst=", lst)

আউটপুট:

lst= [1, 2, 3, 4, 5]
shift by 1: [2, 3, 4, 5, 1]
lst= [1, 2, 3, 4, 5]
shift by 7: [3, 4, 5, 1, 2]
lst= [1, 2, 3, 4, 5]
shift by 1 reverse: [5, 1, 2, 3, 4]
lst= [1, 2, 3, 4, 5]
shift by 7 reverse: [4, 5, 1, 2, 3]
lst= [1, 2, 3, 4, 5]

0

প্রোগ্রামিংn পার্লসে জোন বেন্টলি (কলাম 2) পজিশনের xদ্বারা বামে- এলিমেন্ট ভেক্টরটি ঘোরানোর জন্য একটি মার্জিত এবং দক্ষ অ্যালগরিদম বর্ণনা করেছেন i:

এর অ্যারে রূপান্তর যেমন সমস্যা দেখতে যাক abঅ্যারের মধ্যে ba, কিন্তু এর আরো অনুমান যে আমরা একটি ফাংশন যে অ্যারের একটি নির্দিষ্ট অংশ উপাদান reverses ছেড়ে দিও। থেকে শুরু করে ab, আমরা বিপরীত aপেতে , বিপরীত পেতে , এবং তারপর পুরো জিনিস বিপরীত পেতে , যা ঠিক । ঘূর্ণনের জন্য নিম্নলিখিত কোডে এর ফলাফল:arbbarbr(arbr)rba

reverse(0, i-1)
reverse(i, n-1)
reverse(0, n-1)

এটি পাইথনে অনুবাদ করা যেতে পারে:

def rotate(x, i):
    i %= len(x)
    x[:i] = reversed(x[:i])
    x[i:] = reversed(x[i:])
    x[:] = reversed(x)
    return x

ডেমো:

>>> def rotate(x, i):
...     i %= len(x)
...     x[:i] = reversed(x[:i])
...     x[i:] = reversed(x[i:])
...     x[:] = reversed(x)
...     return x
... 
>>> rotate(list('abcdefgh'), 1)
['b', 'c', 'd', 'e', 'f', 'g', 'h', 'a']
>>> rotate(list('abcdefgh'), 3)
['d', 'e', 'f', 'g', 'h', 'a', 'b', 'c']
>>> rotate(list('abcdefgh'), 8)
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
>>> rotate(list('abcdefgh'), 9)
['b', 'c', 'd', 'e', 'f', 'g', 'h', 'a']

0

তালিকার দৈর্ঘ্যের চেয়ে কম তালিকা X = ['a', 'b', 'c', 'd', 'e', 'f']এবং একটি পছন্দসই শিফ্ট মানের জন্য আমরা ফাংশনটি নীচে হিসাবে সংজ্ঞায়িত করতে পারিshift list_shift()

def list_shift(my_list, shift):
    assert shift < len(my_list)
    return my_list[shift:] + my_list[:shift]

উদাহরণ,

list_shift(X,1)রিটার্ন ['b', 'c', 'd', 'e', 'f', 'a'] list_shift(X,3)দেয়['d', 'e', 'f', 'a', 'b', 'c']


1
ওপিতে ঠিক তেমনটাই রয়েছে। আপনি সবেমাত্র নাম পরিবর্তন করেছেন এবং একটি জোড় যুক্ত করেছেন।
RufusVS

ফাংশন list_shiftআপনার উত্তর ফাংশন অভিন্ন shift, মূল প্রশ্নে তাই এই প্রকৃত প্রশ্নের উত্তর নয়: "সেখানে একটি ভাল উপায় আছে?"
RufusVS

0
def solution(A, K):
    if len(A) == 0:
        return A

    K = K % len(A)

    return A[-K:] + A[:-K]

# use case
A = [1, 2, 3, 4, 5, 6]
K = 3
print(solution(A, K))

উদাহরণস্বরূপ, দেওয়া

A = [3, 8, 9, 7, 6]
K = 3

ফাংশন ফিরে আসা উচিত [9, 7, 6, 3, 8]। তিনটি আবর্তন করা হয়েছিল:

[3, 8, 9, 7, 6] -> [6, 3, 8, 9, 7]
[6, 3, 8, 9, 7] -> [7, 6, 3, 8, 9]
[7, 6, 3, 8, 9] -> [9, 7, 6, 3, 8]

অন্য একটি উদাহরণের জন্য, দেওয়া

A = [0, 0, 0]
K = 1

ফাংশন ফিরে আসা উচিত [0, 0, 0]

প্রদত্ত

A = [1, 2, 3, 4]
K = 4

ফাংশন ফিরে আসা উচিত [1, 2, 3, 4]


0

আমি এই সমস্যার জায়গায় সমাধান খুঁজছিলাম। এটি ও (কে) এর উদ্দেশ্য সমাধান করে।

def solution(self, list, k):
    r=len(list)-1
    i = 0
    while i<k:
        temp = list[0]
        list[0:r] = list[1:r+1]
        list[r] = temp
        i+=1
    return list

-3

অন্যান্য ভাষায় শিফটের মতো কার্যকারিতার জন্য:

def shift(l):
    x = l[0]
    del(l[0])
    return x

1
-1: এটি যা জিজ্ঞাসা করা হয়েছে তার থেকে আলাদা কিছু করছে, এবং বিটিডাব্লুও সমানL.pop(0)
6502
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.