ලැයිස්තුවක් ඒකාකාර ප්‍රමාණයේ කැබලිවලට බෙදන්නේ කෙසේද?


2288

මා සතුව අත්තනෝමතික දිග ලැයිස්තුවක් ඇති අතර, එය සමාන ප්‍රමාණයේ කැබලිවලට බෙදී එය ක්‍රියාත්මක කිරීමට මට අවශ්‍යය. කවුන්ටරයක් ​​සහ ලැයිස්තු දෙකක් තබා ගැනීම වැනි පැහැදිලි ක්‍රම කිහිපයක් තිබේ, දෙවන ලැයිස්තුව පුරවන විට, එය පළමු ලැයිස්තුවට එකතු කර ඊළඟ වටයේ දත්ත සඳහා දෙවන ලැයිස්තුව හිස් කරන්න, නමුත් මෙය අතිශයින්ම මිල අධික විය හැකිය.

ඕනෑම දිග ලැයිස්තුවක් සඳහා යමෙකුට හොඳ විසඳුමක් තිබේදැයි මම කල්පනා කළෙමි, උදා: ජනක යන්ත්‍ර භාවිතා කිරීම.

මම ප්‍රයෝජනවත් යමක් සොයමින් itertoolsසිටියද මට පැහැදිලිවම ප්‍රයෝජනවත් කිසිවක් සොයාගත නොහැකි විය. සමහර විට එය මග හැරී ඇත.

ආශ්‍රිත ප්‍රශ්නය: කුට්ටි ලැයිස්තුවක් හරහා නැවත සැකසීමට වඩාත්ම “පයිතොනික්” ක්‍රමය කුමක්ද?


1
ඔබ නව පිළිතුරක් පළ කිරීමට පෙර, මෙම ප්‍රශ්නයට පිළිතුරු 60+ ක් දැනටමත් ඇති බව සලකන්න. කරුණාකර, ඔබගේ පිළිතුර දැනට පවතින පිළිතුරු අතර නොමැති තොරතුරු සඳහා දායක වන බවට වග බලා ගන්න.
janniks

අත්තනෝමතික ලෙස කුඩා අවසාන කැබැල්ලක් වළක්වා ගැනීමට කැමති පරිශීලකයින් සඳහා, ආසන්න වශයෙන් සමාන දිගකින් යුත් N කොටස් වලට ලැයිස්තුවක් බෙදීම
wim

Answers:


3186

ඔබට අවශ්‍ය කුට්ටි ලබා දෙන ජනක යන්ත්‍රයක් මෙන්න:

def chunks(lst, n):
    """Yield successive n-sized chunks from lst."""
    for i in range(0, len(lst), n):
        yield lst[i:i + n]

import pprint
pprint.pprint(list(chunks(range(10, 75), 10)))
[[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
 [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
 [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
 [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
 [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
 [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
 [70, 71, 72, 73, 74]]

ඔබ පයිතන් 2 භාවිතා කරන්නේ නම්, xrange()ඒ වෙනුවට ඔබ භාවිතා කළ යුත්තේ range():

def chunks(lst, n):
    """Yield successive n-sized chunks from lst."""
    for i in xrange(0, len(lst), n):
        yield lst[i:i + n]

ඔබේ කේතය තේරුම් ගැනීමට පහසු වන පරිදි නම් කරන ලද ශ්‍රිතයන්හි මෙවැනි ක්‍රියාකාරකම් සංයුක්ත කිරීම හොඳ අදහසක් වුවද ඔබට ශ්‍රිතයක් ලිවීම වෙනුවට ලැයිස්තු අවබෝධය භාවිතා කළ හැකිය. පයිතන් 3:

[lst[i:i + n] for i in range(0, len(lst), n)]

පයිතන් 2 අනුවාදය:

[lst[i:i + n] for i in xrange(0, len(lst), n)]

73
ලැයිස්තුවේ දිග අපට කිව නොහැකි නම් කුමක් සිදුවේද? Itertools.repeat ([1, 2, 3]) හි මෙය උත්සාහ කරන්න, උදා
jespern

48
එය ප්‍රශ්නයට සිත්ගන්නා සුළු දිගුවකි, නමුත් මුල් ප්‍රශ්නය පැහැදිලිවම ලැයිස්තුවක් මත ක්‍රියාත්මක වීම ගැන විමසීය.
නෙඩ් බැට්චෙල්ඩර්

36
මෙම කාර්යයන් ඉතා සම්මත පුස්තකාලයේ තිබිය යුතුය
dgan

6
Al කැලිමෝ: ඔබ යෝජනා කරන්නේ කුමක්ද? මූලද්රව්ය 47 ක් සහිත ලැයිස්තුවක් මම ඔබට භාර දෙමි. එය "ඒකාකාර ප්‍රමාණයේ කුට්ටි" වලට බෙදීමට ඔබ කැමති වන්නේ කෙසේද? OP පිළිතුර පිළිගත්තේය, එබැවින් ඔවුන් අවසාන වශයෙන් වෙනස් ප්‍රමාණයේ කැබැල්ල සමඟ හොඳින් ගැලපේ. සමහර විට ඉංග්‍රීසි වාක්‍ය ඛණ්ඩය නිරවද්‍යද?
නෙඩ් බැට්චෙල්ඩර්

8
කරුණාකර ඔබේ විචල්‍යයන් l ලෙස නම් නොකරන්න, එය හරියටම 1 මෙන් පෙනෙන අතර ව්‍යාකූල වේ. මිනිස්සු ඔබේ කේතය පිටපත් කරන අතර මෙය හරි යැයි සිතති.
යසෙන්

560

ඔබට සුපිරි සරල දෙයක් අවශ්‍ය නම්:

def chunks(l, n):
    n = max(1, n)
    return (l[i:i+n] for i in range(0, len(l), n))

පයිතන් 2.x xrange()වෙනුවට භාවිතා කරන්නrange()


6
නැතහොත් (අපි මෙම විශේෂිත ශ්‍රිතයේ විවිධ නිරූපණයන් කරන්නේ නම්) ඔබට ලැම්බඩා ශ්‍රිතය අර්ථ දැක්විය හැක්කේ: ලැම්බඩා x, y: [x [i: i + y] i පරාසය සඳහා (0, ලෙන් (x), y) ]. මම මෙම ලැයිස්තු-තේරුම් ගැනීමේ ක්‍රමයට කැමතියි!
ජේපී

4
ආපසු පැමිණි පසු [, නොව (
alwbtc

2
“සුපිරි සරල” යන්නෙන් අදහස් කරන්නේ අසීමිත ලූප නිදොස් කිරීම නොකිරීමයි max().
බොබ් ස්ටේන්

මෙම විසඳුම පිළිබඳ සරල දෙයක් නොමැත
mit

1
HNhoj_Gonk අපොයි එය අසීමිත පුඩුවක් නොවේ, නමුත් කුට්ටි (L, 0) උපරිම () නොමැතිව අගය දෝෂයක් මතු කරයි. ඒ වෙනුවට, උපරිම () 1 ට අඩු ඕනෑම දෙයක් 1 බවට හරවයි.
බොබ් ස්ටේන්

297

(පැරණි) පයිතන් ප්‍රලේඛනයෙන් (itertools සඳහා වට්ටෝරු) කෙලින්ම:

from itertools import izip, chain, repeat

def grouper(n, iterable, padvalue=None):
    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
    return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)

වර්තමාන අනුවාදය, JFSebastian විසින් යෝජනා කළ පරිදි:

#from itertools import izip_longest as zip_longest # for Python 2.x
from itertools import zip_longest # for Python 3.x
#from six.moves import zip_longest # for both (uses the six compat library)

def grouper(n, iterable, padvalue=None):
    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
    return zip_longest(*[iter(iterable)]*n, fillvalue=padvalue)

මම හිතන්නේ ගයිඩෝගේ කාල යන්ත්‍ර වැඩ - වැඩ කළා - වැඩ කරයි - වැඩ කරයි - නැවත වැඩ කරයි.

මෙම විසඳුම් ක්‍රියාත්මක වන්නේ [iter(iterable)]*n(හෝ පෙර අනුවාදයට සමාන) ලැයිස්තුවේ එක්n වාරයක් නැවත නැවත නිර්මාණය කරන බැවිනි. izip_longestඉන්පසු "එක් එක්" අනුකාරකයේ රවුන්ඩ් රොබින් effectively ලදායී ලෙස සිදු කරයි; මෙය එකම අනුකාරකයක් වන බැවින්, එය එක් එක් ඇමතුම මගින් දියුණු වන අතර, එහි ප්‍රති ing ලයක් ලෙස එක් එක් සිප්-රවුන්ඩ්‍රෝබින් මඟින් එක් nඅයිතමයක් ජනනය වේ .


inninjagecko: list(grouper(3, range(10)))ප්‍රතිලාභ [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)], සහ සියලු ටුපල් වල දිග 3. කරුණාකර ඔබේ අදහස මට තේරුම් ගත නොහැකි නිසා එය විස්තර කරන්න; ඔබ යම් දෙයක් හඳුන්වන්නේ කුමක්ද සහ එය “ඔබේ දේ 3 න් ගුණ කිරීමක් වනු ඇතැයි අපේක්ෂා කිරීම” තුළ එය 3 න් ගුණ කිරීමක් ලෙස අර්ථ දක්වන්නේ කෙසේද? ඔයාට කලින්ම ස්තූතියි.
tzot

14
මෙය උත්පාදනය කළේ එය ජනක යන්ත්‍ර මත ක්‍රියා කරන නිසා (කාචයක් නැත) සහ සාමාන්‍යයෙන් වේගවත් ඉටර්ටූල් මොඩියුලය භාවිතා කරන බැවිනි.
මයිකල් ඩිලන්

89
itertoolsසරල හා අහිංසක පිරිසිදු පයිතන් ක්‍රියාවට නැංවීම හා සසඳන විට, කියවිය නොහැකි රොන්මඩ ඉවත් කිරීම සඳහා විසිතුරු ක්‍රියාකාරී ප්‍රවේශය පිළිබඳ හොඳම උදාහරණය
wim

15
imwim මෙම පිළිතුර ආරම්භ වූයේ පයිතන් ප්‍රලේඛනයේ කුඩා කොටසක් ලෙස බැවින්, bugs.python.org හි ගැටළුවක් විවෘත කිරීමට මම ඔබට යෝජනා කරමි .
tzot

1
@pedrosaurio නම් l==[1, 2, 3]එවිට f(*l)ද සමාන වේ f(1, 2, 3). බලන්න ඒ ප්රශ්නය සහ නිල ප්රලේඛනය .
tzot

231

මෙය පැරණි බව මම දනිමි, නමුත් කිසිවෙකු තවමත් සඳහන් කර නැත numpy.array_split:

import numpy as np

lst = range(50)
np.array_split(lst, 5)
# [array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
#  array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
#  array([20, 21, 22, 23, 24, 25, 26, 27, 28, 29]),
#  array([30, 31, 32, 33, 34, 35, 36, 37, 38, 39]),
#  array([40, 41, 42, 43, 44, 45, 46, 47, 48, 49])]

12
මෙය ඔබට කැබලි ගණනක මූලද්‍රව්‍ය ගණන නොව මුළු කුට්ටි ගණන සැකසීමට ඉඩ දෙයි.
FizxMike

6
ඔබට ගණිතය තනිවම කළ හැකිය. ඔබට මූලද්රව්ය 10 ක් තිබේ නම්, ඔබට ඒවා මූලද්රව්ය 2, 5 ක් හෝ මූලද්රව්ය 5 ක් ලෙස කොටස් කළ හැකිය
Moj

24
+1 මෙය මගේ ප්‍රියතම විසඳුමයි, එය අරාව ඒකාකාර ප්‍රමාණයේ අරා වලට බෙදන අතර අනෙක් විසඳුම් එසේ නොවේ (මා බැලූ අනෙක් සියලුම විසඳුම් වලදී, අවසාන අරාව අත්තනෝමතික ලෙස කුඩා විය හැක).
මිනි ක්වාර්ක්

InMiniQuark නමුත් කුට්ටි ගණන මුල් අරාව ප්‍රමාණයට සාධකයක් නොවන විට මෙය කරන්නේ කුමක්ද?
බෝල්ඩ්රික්

1
Ald බෝල්ඩ්‍රික් ඔබ N මූලද්‍රව්‍ය K කුට්ටි වලට බෙදුවහොත් පළමු N% K කුට්ටි වල N // K + 1 මූලද්‍රව්‍යද අනෙක් ඒවාට N // K මූලද්‍රව්‍යද ඇත. උදාහරණයක් ලෙස, ඔබ මූලද්රව්ය 108 කින් යුත් අරාවක් කුට්ටි 5 කට බෙදුවහොත්, පළමු 108% 5 = 3 කුට්ටි 108 // 5 + 1 = 22 මූලද්රව්ය අඩංගු වන අතර ඉතිරි කුට්ටි 108 // 5 = 21 මූලද්රව්ය.
මිනි ක්වාර්ක්

152

මම පුදුම කිසිවෙක් භාවිතා සිතා ඇත්තේ ඉන්නේ iterගේ ද්වි-තර්කය ආකෘති පත්රය :

from itertools import islice

def chunk(it, size):
    it = iter(it)
    return iter(lambda: tuple(islice(it, size)), ())

නිරූපණය:

>>> list(chunk(range(14), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13)]

මෙය ඕනෑම ක්‍රියාකාරීත්වයකින් ක්‍රියා කරන අතර ප්‍රතිදානය කම්මැලි ලෙස නිපදවයි. එය ඉරේටරයට වඩා ටුපල් නැවත ලබා දෙයි, නමුත් මම හිතන්නේ එයට යම් අලංකාරයක් ඇත. එය ද පෑඩ් නොවේ; ඔබට පෑඩින් කිරීමට අවශ්‍ය නම්, ඉහත සඳහන් සරල විචලනය ප්‍රමාණවත් වේ:

from itertools import islice, chain, repeat

def chunk_pad(it, size, padval=None):
    it = chain(iter(it), repeat(padval))
    return iter(lambda: tuple(islice(it, size)), (padval,) * size)

නිරූපණය:

>>> list(chunk_pad(range(14), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, None)]
>>> list(chunk_pad(range(14), 3, 'a'))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 'a')]

izip_longestපදනම් වූ විසඳුම් මෙන් , ඉහත සෑම විටම පෑඩ්. මා දන්නා පරිදි, විකල්පයක් ලෙස පෑඩ් කරන ශ්‍රිතයක් සඳහා පේළි එකක් හෝ දෙකක ඉටර්ටූල් වට්ටෝරුවක් නොමැත . ඉහත ප්‍රවේශයන් දෙක ඒකාබද්ධ කිරීමෙන්, මෙය ඉතා සමීප වේ:

_no_padding = object()

def chunk(it, size, padval=_no_padding):
    if padval == _no_padding:
        it = iter(it)
        sentinel = ()
    else:
        it = chain(iter(it), repeat(padval))
        sentinel = (padval,) * size
    return iter(lambda: tuple(islice(it, size)), sentinel)

නිරූපණය:

>>> list(chunk(range(14), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13)]
>>> list(chunk(range(14), 3, None))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, None)]
>>> list(chunk(range(14), 3, 'a'))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 'a')]

විකල්ප පැඩින් ලබා දෙන යෝජිත කෙටිම කුටිය මෙය බව මම විශ්වාස කරමි.

ටොමාස් ගන්ඩෝර් නිරීක්ෂණය කළ පරිදි , පැඩිං කුට්ටි දෙක දිගු පෑඩ් අගයන් හමු වුවහොත් අනපේක්ෂිත ලෙස නතර වනු ඇත. මෙන්න එම ගැටළුව සාධාරණ ආකාරයකින් ක්‍රියාත්මක වන අවසාන විචලනයකි:

_no_padding = object()
def chunk(it, size, padval=_no_padding):
    it = iter(it)
    chunker = iter(lambda: tuple(islice(it, size)), ())
    if padval == _no_padding:
        yield from chunker
    else:
        for ch in chunker:
            yield ch if len(ch) == size else ch + (padval,) * (size - len(ch))

නිරූපණය:

>>> list(chunk([1, 2, (), (), 5], 2))
[(1, 2), ((), ()), (5,)]
>>> list(chunk([1, 2, None, None, 5], 2, None))
[(1, 2), (None, None), (5, None)]

7
පුදුමයි, ඔබේ සරල අනුවාදය මගේ ප්‍රියතමය. තවත් සමහරු මූලික islice(it, size)ප්‍රකාශනය ඉදිරිපත් කර එය (මා කළ පරිදි) ලූප ඉදිකිරීමක් තුළට කාවැද්දූහ. iter()(මම සම්පූර්ණයෙන්ම නොදැන සිටියෙමි) තර්ක දෙකේ අනුවාදය ගැන ඔබ සිතුවේ එය සුපිරි අලංකාර (සහ බොහෝ විට කාර්ය සාධනය-effective ලදායී) කරයි. iterසෙන්ඩිනල් එක ලබා දුන් විට 0-තර්ක ශ්‍රිතයකට වෙනස් වන පළමු තර්කය මා නොදැන සිටියෙමි . ඔබ කුට්ටි (බඳුනක්, අසීමිත) අනුකාරකයක් නැවත ලබා දෙයි, ආදාන ලෙස (බඳුනක්, අනන්ත) අනුකාරකයක් භාවිතා කළ හැකිය, len()අරා පෙති නොමැත. නියමයි!
තෝමස් එච්

1
ඉහළම යුවළ පමණක් පරිලෝකනය කරනවාට වඩා මම පිළිතුරු කියවන්නේ මේ නිසා ය. මගේ නඩුවේදී විකල්ප පෑඩින් කිරීම අවශ්‍යතාවයක් වූ අතර, මමත් එයර්ගේ තර්ක දෙකේ ස්වරූපය ගැන ඉගෙන ගතිමි.
කර්

මම මෙය ඉහළට ඔසවා තැබුවෙමි, නමුත් තවමත් - අපි එය ඉක්මවා නොයමු! පළමුවෙන්ම, ලැම්බඩා නරක විය හැකිය ( itඅනුකාරකයට වඩා සෙමින් වසා දැමීම . දෙවනුව, සහ බොහෝ padval
ආනයන ද්‍රව්‍ය

Oma ටොමාස්ගන්ඩර්, මම ඔබේ පළමු කරුණ සලකා බලමි! ලැම්බඩා සාමාන්‍ය ශ්‍රිතයකට වඩා මන්දගාමී නොවන බව මගේ අවබෝධය වුවද, ඇත්ත වශයෙන්ම ඔබ ක්‍රියාකාරී ඇමතුම සහ වසා දැමීමේ පෙනුම මෙය මන්දගාමී වනු ඇති බව ඔබ නිවැරදිය. මෙහි සාපේක්ෂ කාර්ය සාධනයට එදිරිව izip_longestප්‍රවේශය කුමක් වේදැයි මම නොදනිමි. උදාහරණයක් ලෙස - එය සංකීර්ණ වෙළඳාමක් විය හැකි යැයි මම සැක කරමි. නමුත් ... පරාමිතියක් padvalඉදිරිපත් කරන සෑම පිළිතුරකින්ම ගැටලුව බෙදා padvalනොගනීද?
යවන්නා

1
@ ටොමාස්ගන්ඩර්, ප්‍රමාණවත්! නමුත් මෙය නිවැරදි කරන අනුවාදයක් නිර්මාණය කිරීම එතරම් අපහසු නොවීය. (එසේම, සම්බන්ධ වන භාවිතා කරන පළමු අනුවාදය, ඒ ()මේ නිදහස ලෙස, කරන්නේ . වැඩ නිවැරදිව මෙයට හේතුව වන්නේ tuple(islice(it, size))අස්වැන්න ()විට it. හිස්)
senderle

94

අත්තනෝමතික පුනරාවර්තන මත ක්‍රියා කරන ජනක යන්ත්‍රයක් මෙන්න:

def split_seq(iterable, size):
    it = iter(iterable)
    item = list(itertools.islice(it, size))
    while item:
        yield item
        item = list(itertools.islice(it, size))

උදාහරණයක්:

>>> import pprint
>>> pprint.pprint(list(split_seq(xrange(75), 10)))
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
 [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
 [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
 [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
 [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
 [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
 [70, 71, 72, 73, 74]]

53
def chunk(input, size):
    return map(None, *([iter(input)] * size))

map(None, iter)සමානයි izip_longest(iter).
තෝමස් අහ්ලේ

1
@TomaszWysocki ඔබට *ඉදිරියෙන් ඇති iterator tuple පැහැදිලි කළ හැකිද ? ඔබේ පිළිතුරු පා text යේ විය හැක, නමුත් *මීට පෙර පයිතන්හි එය එසේ භාවිතා කර ඇති බව මම දැක ඇත්තෙමි . ස්තූතියි!
TheJollySin

1
JtheJollySin මෙම සන්දර්භය තුළ එය ස්ප්ලට් ක්‍රියාකරු ලෙස හැඳින්වේ. එහි භාවිතය මෙහි විස්තර කර ඇත - stackoverflow.com/questions/5917522/unzipping-and-the-operator .
rlms

2
වසන්න නමුත් අන්තිම කැබැල්ලට එය පුරවා ගැනීමට මූලද්‍රව්‍ය කිසිවක් නොමැත. මෙය අඩුපාඩුවක් හෝ නොවිය හැකිය. ඇත්තෙන්ම සිසිල් රටාව.

49

සරල නමුත් අලංකාරයි

l = range(1, 1000)
print [l[x:x+10] for x in xrange(0, len(l), 10)]

හෝ ඔබ කැමති නම්:

def chunks(l, n): return [l[x: x+n] for x in xrange(0, len(l), n)]
chunks(l, 10)

18
අරාබි අංකයකට සමාන විචල්‍යයක් ඔබ විසින් නොකියන්න. සමහර අකුරු වල, 1සහ lවෙන් කළ නොහැකි ය. මෙන් 0සහ O. සමහර විට පවා Iසහ 1.
ඇල්ෆ්

14
අඩුපාඩු සහිත අකුරු. මිනිසුන් එවැනි අකුරු භාවිතා නොකළ යුතුය. වැඩසටහන්ගත කිරීම සඳහා, සඳහා නො දෙයක් .
ජෙරී බී

17
ලැම්බඩාස් නම් නොකල ශ්‍රිත ලෙස භාවිතා කිරීමට අදහස් කෙරේ. ඒවා එසේ භාවිතා කිරීමෙන් පලක් නැත. ඊට අමතරව එය නිදොස් කිරීම වඩාත් අපහසු කරයි, දෝෂයක් ඇති වුවහොත් හෝඩුවාව “කුට්ටි” වෙනුවට “<lambda>” ලෙස වාර්තා කරයි. ඔබට මේ සියල්ලම තිබේ නම් ඔබට ගැටලුවක් සොයා ගැනීමට වාසනාව ලැබේවායි ප්‍රාර්ථනා කරමි :)
ක්‍රිස් කොස්ටන්

1
එය 0 විය යුතු අතර xrange ඇතුළත 1 නොවිය යුතුයprint [l[x:x+10] for x in xrange(1, len(l), 10)]
ස්කොටිඩෙල්ටා

සටහන: පයිතන් 3 භාවිතා කරන්නන් සඳහා range.
ක්‍රිස්ටියන් ඩීන්

40

මෙහි වෙනත් පිළිතුරු විවේචනය කිරීම:

මෙම පිළිතුරු කිසිවක් ඒකාකාර ප්‍රමාණයේ කුට්ටි නොවේ, ඒවා සියල්ලම අවසානයේ රන්ට් කැබැල්ලක් තබයි, එබැවින් ඒවා සම්පූර්ණයෙන්ම සමතුලිත නොවේ. වැඩ බෙදා හැරීම සඳහා ඔබ මෙම කාර්යයන් භාවිතා කරන්නේ නම්, ඔබ අනෙක් අය ඉදිරියේ හොඳට වැඩ නිම කිරීමේ අපේක්ෂාව ගොඩනඟා ගෙන ඇත, එබැවින් අනෙක් අය දිගින් දිගටම වෙහෙස මහන්සි වී වැඩ කරන අතර එය කිසිවක් නොකර වාඩි වනු ඇත.

උදාහරණයක් ලෙස, වත්මන් ඉහළ පිළිතුර අවසන් වන්නේ:

[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74]]

මම අන්තිමට වෛර කරනවා!

අනෙක් අය, කැමති list(grouper(3, xrange(7))), සහ chunk(xrange(7), 3)දෙදෙනාම ආපසු පැමිණේ : [(0, 1, 2), (3, 4, 5), (6, None, None)]. මෙම Noneනිකමට පිරවුම අතර, මගේ මතය වෙනුවට inelegant. ඒවා ඒකාකාරව කප්පාදු නොකරයි.

අපට මේවා වඩා හොඳින් බෙදිය නොහැක්කේ ඇයි?

මගේ විසඳුම (ය)

මෙහි සමබර විසඳුමක්, මම නිෂ්පාදනය සඳහා යොදා ගන්නා තියෙනවා උත්සවයකට (ආදේශ කිරීමට Python 3 සටහන අනුවර්තනය xrangeසමග range):

def baskets_from(items, maxbaskets=25):
    baskets = [[] for _ in xrange(maxbaskets)] # in Python 3 use range
    for i, item in enumerate(items):
        baskets[i % maxbaskets].append(item)
    return filter(None, baskets) 

මම ජනක යන්ත්‍රයක් නිර්මාණය කළෙමි, ඔබ එය ලැයිස්තුවකට දැමුවහොත් එය එසේම වේ:

def iter_baskets_from(items, maxbaskets=3):
    '''generates evenly balanced baskets from indexable iterable'''
    item_count = len(items)
    baskets = min(item_count, maxbaskets)
    for x_i in xrange(baskets):
        yield [items[y_i] for y_i in xrange(x_i, item_count, baskets)]

අවසාන වශයෙන්, ඉහත සියළු කාර්යයන් මූලද්‍රව්‍යයන් අනුපිළිවෙලින් නැවත ලබා දෙන බව මා දකින බැවින් (ඒවා ලබා දී ඇති පරිදි):

def iter_baskets_contiguous(items, maxbaskets=3, item_count=None):
    '''
    generates balanced baskets from iterable, contiguous contents
    provide item_count if providing a iterator that doesn't support len()
    '''
    item_count = item_count or len(items)
    baskets = min(item_count, maxbaskets)
    items = iter(items)
    floor = item_count // baskets 
    ceiling = floor + 1
    stepdown = item_count % baskets
    for x_i in xrange(baskets):
        length = ceiling if x_i < stepdown else floor
        yield [items.next() for _ in xrange(length)]

ප්‍රතිදානය

ඒවා පරීක්ෂා කිරීමට:

print(baskets_from(xrange(6), 8))
print(list(iter_baskets_from(xrange(6), 8)))
print(list(iter_baskets_contiguous(xrange(6), 8)))
print(baskets_from(xrange(22), 8))
print(list(iter_baskets_from(xrange(22), 8)))
print(list(iter_baskets_contiguous(xrange(22), 8)))
print(baskets_from('ABCDEFG', 3))
print(list(iter_baskets_from('ABCDEFG', 3)))
print(list(iter_baskets_contiguous('ABCDEFG', 3)))
print(baskets_from(xrange(26), 5))
print(list(iter_baskets_from(xrange(26), 5)))
print(list(iter_baskets_contiguous(xrange(26), 5)))

මුද්‍රණය කරන්නේ කුමක්ද:

[[0], [1], [2], [3], [4], [5]]
[[0], [1], [2], [3], [4], [5]]
[[0], [1], [2], [3], [4], [5]]
[[0, 8, 16], [1, 9, 17], [2, 10, 18], [3, 11, 19], [4, 12, 20], [5, 13, 21], [6, 14], [7, 15]]
[[0, 8, 16], [1, 9, 17], [2, 10, 18], [3, 11, 19], [4, 12, 20], [5, 13, 21], [6, 14], [7, 15]]
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14], [15, 16, 17], [18, 19], [20, 21]]
[['A', 'D', 'G'], ['B', 'E'], ['C', 'F']]
[['A', 'D', 'G'], ['B', 'E'], ['C', 'F']]
[['A', 'B', 'C'], ['D', 'E'], ['F', 'G']]
[[0, 5, 10, 15, 20, 25], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]]
[[0, 5, 10, 15, 20, 25], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]]
[[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]]

පරස්පර උත්පාදක යන්ත්රය අනෙක් දෙක මෙන් එකම දිග රටාවකින් කුට්ටි සපයන බව සලකන්න, නමුත් අයිතම සියල්ලම පිළිවෙලට ඇති අතර ඒවා එකිනෙකට සමාන ලෙස බෙදී ඇති අතර ඒවා එකිනෙකට වෙනස් මූලද්‍රව්‍ය ලැයිස්තුවක් බෙදිය හැකිය.


ඉහත කිසිවක් ඒකාකාර ප්‍රමාණයේ කුට්ටි ලබා නොදෙන බව ඔබ කියයි. නමුත් මේ එක මෙන්, කරන්නේ මෙම එක් .
යවන්නා

1
end සෙන්ඩර්ල්, පළමු එක, list(grouper(3, xrange(7)))සහ දෙවැන්න chunk(xrange(7), 3)යන දෙකම නැවත පැමිණේ : [(0, 1, 2), (3, 4, 5), (6, None, None)]. මෙම Noneනිකමට පිරවුම අතර, මගේ මතය වෙනුවට inelegant. ඒවා ඒකාකාරව කප්පාදු නොකරයි. ඔබගේ ඡන්දයට ස්තූතියි!
ආරොන් හෝල්

4
සමාන ප්‍රශ්නයක් (අන්තිම හැර, නොහැකි නම්) හෝ සමබර (හැකි තරම් හොඳ) ප්‍රති result ලයක් බොහෝ විට අවශ්‍ය වන්නේ කුමක් ද යන ප්‍රශ්නය ඔබ (එය පැහැදිලිව නොකර, මම දැන් මෙහි කරමි). සමබර විසඳුම කැමති බව ඔබ උපකල්පනය කරයි; ඔබ වැඩසටහන් කරන දේ සැබෑ ලෝකයට සමීප නම් මෙය සත්‍යයක් විය හැකිය (උදා: අනුකම්පිත කාඩ් ක්‍රීඩාවක් සඳහා කාඩ් ගනුදෙනු ඇල්ගොරිතම). වෙනත් අවස්ථාවල දී (වචන වලින් රේඛා පිරවීම වැනි) යමෙක් කැමති වන්නේ පේළි හැකි තරම් පූර්ණ ලෙස තබා ගැනීමට ය. ඒ නිසා මට එකකට වඩා වැඩි කැමැත්තක් දැක්විය නොහැක. ඒවා විවිධ භාවිත අවස්ථා සඳහා පමණි.
ඇල්ෆ්

@ ක්‍රිස්ටෝපර්බරිංටන්-ලී ඩේටා ෆ්‍රේම්ස් සඳහා, ඔබ බොහෝ විට පෙති භාවිතා කළ යුතුය, මන්ද ඩේටා ෆ්‍රේම් වස්තූන් සාමාන්‍යයෙන් පෙති කැපීමක පිටපත් නොවන බව මම විශ්වාස කරමි, උදාimport pandas as pd; [pd.DataFrame(np.arange(7))[i::3] for i in xrange(3)]
ආරොන් හෝල්

1
A ආරොන්හෝල් අපොයි. මගේ විවේචනය දෙවන වරට අනුමාන කළ නිසා මම මගේ අදහස මකා දැමුවෙමි, නමුත් ඔබ දිනුම් ඇදීමට ඉක්මන් විය. ස්තූතියි! ඇත්ත වශයෙන්ම, එය දත්ත රාමු සඳහා ක්‍රියා නොකරයි යන මගේ ප්‍රකාශය සත්‍යයකි. අයිතම දත්ත රාමුවක් නම්, අන්තිම පේළිය ලෙස අස්වැන්න අයිතම [පරාසය (x_i, අයිතමය_ ගණනය, බාස්කට්)] භාවිතා කරන්න. මම වෙනම (තවත්) පිළිතුරක් ඉදිරිපත් කළෙමි, එහි ඔබ අපේක්ෂිත (අවම) කණ්ඩායම් ප්‍රමාණය නියම කරයි.
CPBL

38

මෙම ප්‍රශ්නයේ අනුපිටපතකින් වඩාත්ම භයානක පයිතන්-ඊෂ් පිළිතුර මම දුටුවෙමි :

from itertools import zip_longest

a = range(1, 16)
i = iter(a)
r = list(zip_longest(i, i, i))
>>> print(r)
[(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, 15)]

ඔබට ඕනෑම n සඳහා n-tuple නිර්මාණය කළ හැකිය. එසේ නම් a = range(1, 15), ප්‍රති result ලය වනුයේ:

[(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, None)]

ලැයිස්තුව සමානව බෙදී තිබේ නම්, ඔබ විස්ථාපනය කල හැකි zip_longestසමග zip, වෙනත් ආකාරයකින් ත්රිත්ව (13, 14, None)අහිමි වනු ඇත. පයිතන් 3 ඉහත භාවිතා වේ. පයිතන් 2 සඳහා, භාවිතා කරන්න izip_longest.


ඔබේ ලැයිස්තුව සහ කුට්ටි කෙටි නම් එය හොඳයි, ඔබේ ලැයිස්තුව 1000 කැබලිවලට බෙදීමට මෙය අනුගත කරන්නේ කෙසේද? ඔබ කේත zip වෙත නොයනු ඇත (i, i, i, i, i, i, i, i, i ..... i = 1000)
ටොම් ස්මිත්

9
zip(i, i, i, ... i)zip () සඳහා "chunk_size" තර්ක සමඟ ලිවිය හැකිය, zip(*[i]*chunk_size)එය හොඳ අදහසක් ද නැද්ද යන්න විවාදාත්මක ය.
විල්සන් එෆ්

1
මෙහි අවාසිය නම්, ඔබ ඒකාකාරව බෙදී නොයන්නේ නම්, කෙටිම නැවත නැවත යෙදිය හැකි පරිදි zip නතර වන බැවින්, ඔබ මූලද්‍රව්‍ය අතහැර දමනු ඇත - & izip_longest මඟින් පෙරනිමි මූලද්‍රව්‍ය එකතු කරනු ඇත.
ආරොන් හෝල්

zip_longestභාවිතා කළ යුතුය, සිදු කර ඇති පරිදි: stackoverflow.com/a/434411/1959808
අයොනිස් ෆිලිපිඩිස්

15 සමඟ නොව range(1, 15)මූලද්‍රව්‍ය 14 ක් ඇති බැවින් පිළිතුර සමඟ දැනටමත් මූලද්‍රව්‍ය අස්ථානගත වී ඇත range(1, 15).
අයොනිස් ෆිලිපිඩිස්

36

ලැයිස්තු ප්‍රමාණය ඔබ දන්නේ නම්:

def SplitList(mylist, chunk_size):
    return [mylist[offs:offs+chunk_size] for offs in range(0, len(mylist), chunk_size)]

ඔබ එසේ නොකරන්නේ නම් (අනුකාරකය):

def IterChunks(sequence, chunk_size):
    res = []
    for item in sequence:
        res.append(item)
        if len(res) >= chunk_size:
            yield res
            res = []
    if res:
        yield res  # yield the last, incomplete, portion

අවසාන අවස්ථාවේ දී, අනුක්‍රමය සෑම විටම දී ඇති ප්‍රමාණයෙන් මුළු කැබලි ගණනක් අඩංගු වන බවට ඔබට සහතික විය හැකි නම් එය වඩාත් සුන්දර ආකාරයකින් නැවත මුද්‍රණය කළ හැකිය (එනම් අසම්පූර්ණ අන්තිම කැබැල්ලක් නොමැත).


මට කණගාටුයි මෙය මෙතරම් පහළට වළලනු ලැබීම. IterChunks සෑම දෙයක් සඳහාම ක්‍රියා කරන අතර එය සාමාන්‍ය විසඳුම වන අතර මා දන්නා කිසිදු අවවාදයක් නොමැත.
ජේසන් ඩන්කල්බර්ගර්

18

උදාහරණයක් ලෙස ඔබට කැබලි 3 ක ප්‍රමාණයක් තිබේ නම්, ඔබට මෙය කළ හැකිය:

zip(*[iterable[i::3] for i in range(3)]) 

මූලාශ්‍රය: http://code.activestate.com/recipes/303060-group-a-list-into-afteential-n-tuples/

මගේ කැබැල්ලේ ප්‍රමාණය ස්ථාවර අංකයක් වන විට මට මෙය ටයිප් කළ හැකිය, උදා: '3', එය කිසි විටෙකත් වෙනස් නොවේ.


11
ලෙන් (නැවත ක්‍රියාත්මක කළ හැකි)% 3! = 0. මෙය ක්‍රියා නොකරයි. අවසාන (කෙටි) සංඛ්‍යා සමූහය ආපසු ලබා නොදේ.
ෂර්බාං

18

මෙම toolz පුස්තකාලය සතුව partitionමේ සඳහා ක්රියාව:

from toolz.itertoolz.core import partition

list(partition(2, [1, 2, 3, 4]))
[(1, 2), (3, 4)]

මෙය සියලු යෝජනා වලින් සරලම ලෙස පෙනේ. එවැනි කොටස් කිරීමේ කාර්යයක් ලබා ගැනීම සඳහා යමෙකුට තෙවන පාර්ශවීය පුස්තකාලයක් භාවිතා කළ යුතු බව ඇත්ත විය හැකිදැයි මම කල්පනා කරමි. එම කොටස් ශ්‍රිතයට සමාන යමක් භාෂා බිල්ඩින් ලෙස පවතිනු ඇතැයි මම අපේක්ෂා කරමි.
kasperd

1
ඔබට itertools සමඟ කොටසක් කළ හැකිය. නමුත් මම මෙවලම් පුස්තකාලයට කැමතියි. එය ක්‍රියාකාරී ශෛලියකින් එකතු කිරීම සඳහා වැඩ කිරීම සඳහා වූ ආනුභාව ලත් පුස්තකාලයකි. ඔබට වෙනස් කළ නොහැකි නමුත් සරල එකතු කිරීම් සඳහා වැඩ කිරීම සඳහා ඔබට කුඩා වචන මාලාවක් ලැබේ. ප්ලස් ලෙස, සයිටූල්ස් සයිතන් වලින් ලියා ඇති අතර එය හොඳ කාර්ය සාධනයක් ලබා ගනී. github.com/pytoolz/cytoolz matthewrocklin.com/blog/work/2014/05/01/Introducing-CyToolz
zach

ඔබ පසුපස කප්පාදුව මඟ හැරියහොත් zach ගේ අදහස් දැක්වීමේ සබැඳිය ක්‍රියා කරයි: matthewrocklin.com/blog/work/2014/05/01/Introducing-CyToolz
mit

16

Tzot සහ JFSebastian විසින් යෝජනා කරන ලද Python doc හි අනුවාදයට මම බොහෝ කැමතියි, නමුත් එහි අඩුපාඩු දෙකක් තිබේ:

  • එය එතරම් පැහැදිලි නැත
  • මට සාමාන්‍යයෙන් අන්තිම කැබැල්ලේ පිරවුම් අගයක් අවශ්‍ය නොවේ

මම මෙය මගේ කේතයේ බොහෝ දේ භාවිතා කරමි:

from itertools import islice

def chunks(n, iterable):
    iterable = iter(iterable)
    while True:
        yield tuple(islice(iterable, n)) or iterable.next()

යාවත්කාලීන කිරීම: කම්මැලි කුට්ටි අනුවාදය:

from itertools import chain, islice

def chunks(n, iterable):
   iterable = iter(iterable)
   while True:
       yield chain([next(iterable)], islice(iterable, n-1))

while Trueලූපය සඳහා විවේක තත්වය කුමක්ද?
wjandrea

@wjandrea: මෙම StopIterationවන විට වර්ධනය tupleහිස් හා iterable.next()ක්රියාත්මක වී යයි. නමුත් නූතන පයිතන් දී නිසි වැඩ කරන්නේ නැහැ, ජෙනරේටරයක් පිටවීමට සිදු කළ යුතු ස්ථාන return, කතා නොකරන්නේ StopIteration. ඒ try/except StopIteration: returnමුළු මහත් පිටුවහලක් වනු වටා (සහ වෙනස් iterable.next()කිරීමට next(iterable)හරස් අනුවාදය compat සඳහා) අවම වශයෙන් අවම පොදු කාර්ය සමග මෙම තීරණය කරනු ලැබේ.
ෂැඩෝ රේන්ජර්

16
[AA[i:i+SS] for i in range(len(AA))[::SS]]

AA අරාව ඇති තැන, SS යනු කුඩා ප්‍රමාණයකි. උදාහරණයක් වශයෙන්:

>>> AA=range(10,21);SS=3
>>> [AA[i:i+SS] for i in range(len(AA))[::SS]]
[[10, 11, 12], [13, 14, 15], [16, 17, 18], [19, 20]]
# or [range(10, 13), range(13, 16), range(16, 19), range(19, 21)] in py3

3
එය හොඳම හා සරල ය.
එෆ්.ටමි

3
කෙටි හා සරල. සංකීර්ණත්වයට වඩා සරල බව.
dkrynicki

15

විවිධ ප්රවේශයන්ගේ ක්රියාකාරිත්වය ගැන මට කුතුහලයක් ඇති වූ අතර මෙන්න එයයි:

පයිතන් 3.5.1 හි පරීක්ෂා කර ඇත

import time
batch_size = 7
arr_len = 298937

#---------slice-------------

print("\r\nslice")
start = time.time()
arr = [i for i in range(0, arr_len)]
while True:
    if not arr:
        break

    tmp = arr[0:batch_size]
    arr = arr[batch_size:-1]
print(time.time() - start)

#-----------index-----------

print("\r\nindex")
arr = [i for i in range(0, arr_len)]
start = time.time()
for i in range(0, round(len(arr) / batch_size + 1)):
    tmp = arr[batch_size * i : batch_size * (i + 1)]
print(time.time() - start)

#----------batches 1------------

def batch(iterable, n=1):
    l = len(iterable)
    for ndx in range(0, l, n):
        yield iterable[ndx:min(ndx + n, l)]

print("\r\nbatches 1")
arr = [i for i in range(0, arr_len)]
start = time.time()
for x in batch(arr, batch_size):
    tmp = x
print(time.time() - start)

#----------batches 2------------

from itertools import islice, chain

def batch(iterable, size):
    sourceiter = iter(iterable)
    while True:
        batchiter = islice(sourceiter, size)
        yield chain([next(batchiter)], batchiter)


print("\r\nbatches 2")
arr = [i for i in range(0, arr_len)]
start = time.time()
for x in batch(arr, batch_size):
    tmp = x
print(time.time() - start)

#---------chunks-------------
def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]
print("\r\nchunks")
arr = [i for i in range(0, arr_len)]
start = time.time()
for x in chunks(arr, batch_size):
    tmp = x
print(time.time() - start)

#-----------grouper-----------

from itertools import zip_longest # for Python 3.x
#from six.moves import zip_longest # for both (uses the six compat library)

def grouper(iterable, n, padvalue=None):
    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
    return zip_longest(*[iter(iterable)]*n, fillvalue=padvalue)

arr = [i for i in range(0, arr_len)]
print("\r\ngrouper")
start = time.time()
for x in grouper(arr, batch_size):
    tmp = x
print(time.time() - start)

ප්රතිපල:

slice
31.18285083770752

index
0.02184295654296875

batches 1
0.03503894805908203

batches 2
0.22681021690368652

chunks
0.019841909408569336

grouper
0.006506919860839844

3
timeඅපට timeitමොඩියුලය ඇති විට පුස්තකාලය භාවිතා කිරීම මිණුම් සලකුණු කිරීම හොඳ අදහසක් නොවේ
අසාත් ඉබ්‍රකොව්

13

කේතය:

def split_list(the_list, chunk_size):
    result_list = []
    while the_list:
        result_list.append(the_list[:chunk_size])
        the_list = the_list[chunk_size:]
    return result_list

a_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

print split_list(a_list, 3)

ප්‍රති result ලය:

[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

12

ඔබට පුස්තකාලයේ get_chunksක්‍රියාකාරිත්වය ද භාවිතා කළ හැකිය utilspie:

>>> from utilspie import iterutils
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> list(iterutils.get_chunks(a, 5))
[[1, 2, 3, 4, 5], [6, 7, 8, 9]]

ඔබට utilspieපයිප්ප හරහා ස්ථාපනය කළ හැකිය:

sudo pip install utilspie

වියාචනය: මම උපයෝගීතා පුස්තකාලයේ නිර්මාතෘ වෙමි .


12

පයිතන් 3.8 හි පැවරුම් ප්‍රකාශන සමඟ එය තරමක් ලස්සනයි:

import itertools

def batch(iterable, size):
    it = iter(iterable)
    while item := list(itertools.islice(it, size)):
        yield item

මෙය ක්‍රියා කරන්නේ ලැයිස්තුවක් පමණක් නොව අත්තනෝමතික ලෙස ය.

>>> import pprint
>>> pprint.pprint(list(batch(range(75), 10)))
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
 [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
 [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
 [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
 [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
 [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
 [70, 71, 72, 73, 74]]

1
දැන් මෙය මෙම ප්‍රශ්නයට සුදුසු නව පිළිතුරකි. මම ඇත්තටම මේකට කැමතියි. පැවරුම් ප්‍රකාශන ගැන මට සැකයක් ඇත, නමුත් ඒවා වැඩ කරන විට ඒවා ක්‍රියාත්මක වේ.
juanpa.arrivillaga

11

මෙම අවස්ථාවේදී, මම හිතන්නේ අපට පුනරාවර්තන උත්පාදක යන්ත්රයක් අවශ්යයි පමණක් නඩුවේ, ...

පයිතන් 2 හි:

def chunks(li, n):
    if li == []:
        return
    yield li[:n]
    for e in chunks(li[n:], n):
        yield e

පයිතන් 3 හි:

def chunks(li, n):
    if li == []:
        return
    yield li[:n]
    yield from chunks(li[n:], n)

එසේම, දැවැන්ත පිටසක්වල ආක්‍රමණයකදී, අලංකාර කරන ලද පුනරාවර්තන උත්පාදක යන්ත්‍රයක් ප්‍රයෝජනවත් විය හැකිය:

def dec(gen):
    def new_gen(li, n):
        for e in gen(li, n):
            if e == []:
                return
            yield e
    return new_gen

@dec
def chunks(li, n):
    yield li[:n]
    for e in chunks(li[n:], n):
        yield e

7

හෙහ්, එක් පේළියේ අනුවාදය

In [48]: chunk = lambda ulist, step:  map(lambda i: ulist[i:i+step],  xrange(0, len(ulist), step))

In [49]: chunk(range(1,100), 10)
Out[49]: 
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
 [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
 [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
 [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
 [41, 42, 43, 44, 45, 46, 47, 48, 49, 50],
 [51, 52, 53, 54, 55, 56, 57, 58, 59, 60],
 [61, 62, 63, 64, 65, 66, 67, 68, 69, 70],
 [71, 72, 73, 74, 75, 76, 77, 78, 79, 80],
 [81, 82, 83, 84, 85, 86, 87, 88, 89, 90],
 [91, 92, 93, 94, 95, 96, 97, 98, 99]]

36
කරුණාකර, "chunk = lambda" වෙනුවට "def chunk" භාවිතා කරන්න. එය එකම ආකාරයකින් ක්රියා කරයි. එක් පේළියක්. එකම ලක්ෂණ. කියවීමට සහ තේරුම් ගැනීමට n00bz ට වඩා පහසුය.
එස්.ලොට්

4
L එස්. ලොට්: n00bz යෝජනා ක්‍රමයෙන් නොවේ නම්: P මෙය සැබෑ ගැටළුවක් නොවේ. ගූගල් වෙත මූල පදයක් පවා තිබේ! n00bz සඳහා අප වළක්වන වෙනත් ලක්ෂණ මොනවාද? මම හිතන්නේ අස්වැන්න එවකට n00b මිත්‍රශීලී වීමට තරම් අත්‍යවශ්‍ය නොවේ.
ජැනස් ට්‍රොල්සන්

16
def chunkවෙනුවට ඇති වන ශ්‍රිත වස්තුවට chunk=lambda.__ name__ ගුණාංගය '<lambda>' වෙනුවට 'chunk' ඇත. ලුහුබැඳීම් වලදී නිශ්චිත නම වඩාත් ප්‍රයෝජනවත් වේ.
ටෙරී ජෑන් රීඩි

1
L ඇල්ෆ්: ප්‍රධාන අර්ථකථන වෙනසක් ලෙස හැඳින්විය හැකිදැයි මට විශ්වාස නැත, නමුත් හෝඩුවාවක් වෙනුවට ප්‍රයෝජනවත් නමක් තිබේද නැද්ද යන්න <lamba>අවම වශයෙන් සැලකිය යුතු වෙනසක් වේ.
මාර්ටිනෝ

1
කාර්ය සාධනය සඳහා ඔවුන්ගෙන් පොකුරක් පරීක්ෂා කිරීමෙන් පසුව, මෙය විශිෂ්ටයි!
සනී පටෙල්

7
def split_seq(seq, num_pieces):
    start = 0
    for i in xrange(num_pieces):
        stop = start + len(seq[i::num_pieces])
        yield seq[start:stop]
        start = stop

භාවිතය:

seq = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

for seq in split_seq(seq, 3):
    print seq

7

තවත් පැහැදිලි අනුවාදයක්.

def chunkList(initialList, chunkSize):
    """
    This function chunks a list into sub lists 
    that have a length equals to chunkSize.

    Example:
    lst = [3, 4, 9, 7, 1, 1, 2, 3]
    print(chunkList(lst, 3)) 
    returns
    [[3, 4, 9], [7, 1, 1], [2, 3]]
    """
    finalList = []
    for i in range(0, len(initialList), chunkSize):
        finalList.append(initialList[i:i+chunkSize])
    return finalList

(2016 සැප්තැම්බර් 12) මෙම පිළිතුර වඩාත්ම භාෂා ස්වාධීන සහ කියවීමට පහසුම වේ.
ඩී ඇඩම්ස්

7

විශාල ලැයිස්තු සඳහා හොඳ වන ලෙන් () ඇමතීමෙන් තොරව:

def splitter(l, n):
    i = 0
    chunk = l[:n]
    while chunk:
        yield chunk
        i += n
        chunk = l[i:i+n]

මෙය පුනරාවර්තන සඳහා වේ:

def isplitter(l, n):
    l = iter(l)
    chunk = list(islice(l, n))
    while chunk:
        yield chunk
        chunk = list(islice(l, n))

ඉහත ක්‍රියාකාරී රසය:

def isplitter2(l, n):
    return takewhile(bool,
                     (tuple(islice(start, n))
                            for start in repeat(iter(l))))

හෝ:

def chunks_gen_sentinel(n, seq):
    continuous_slices = imap(islice, repeat(iter(seq)), repeat(0), repeat(n))
    return iter(imap(tuple, continuous_slices).next,())

හෝ:

def chunks_gen_filter(n, seq):
    continuous_slices = imap(islice, repeat(iter(seq)), repeat(0), repeat(n))
    return takewhile(bool,imap(tuple, continuous_slices))

16
len()විශාල ලැයිස්තු වලක්වා ගැනීමට හේතුවක් නැත ; එය නියත කාලීන මෙහෙයුමකි.
තෝමස් වවුටර්ස්

7

අමතර ප්‍රවේශයන් ලැයිස්තුවක් මෙන්න:

ලබා දී ඇත

import itertools as it
import collections as ct

import more_itertools as mit


iterable = range(11)
n = 3

කේතය

සම්මත පුස්තකාලය

list(it.zip_longest(*[iter(iterable)] * n))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

d = {}
for i, x in enumerate(iterable):
    d.setdefault(i//n, []).append(x)

list(d.values())
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

dd = ct.defaultdict(list)
for i, x in enumerate(iterable):
    dd[i//n].append(x)

list(dd.values())
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

more_itertools+

list(mit.chunked(iterable, n))
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

list(mit.sliced(iterable, n))
# [range(0, 3), range(3, 6), range(6, 9), range(9, 11)]

list(mit.grouper(n, iterable))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

list(mit.windowed(iterable, len(iterable)//n, step=n))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

යොමුව

+ තෙවන පාර්ශවීය පුස්තකාලයක් වන අතර එය ඉටර්ටූල් වට්ටෝරු සහ තවත් දේ ක්‍රියාත්මක කරයි .> pip install more_itertools


6

මෙම යොමුව බලන්න

>>> orange = range(1, 1001)
>>> otuples = list( zip(*[iter(orange)]*10))
>>> print(otuples)
[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), ... (991, 992, 993, 994, 995, 996, 997, 998, 999, 1000)]
>>> olist = [list(i) for i in otuples]
>>> print(olist)
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ..., [991, 992, 993, 994, 995, 996, 997, 998, 999, 1000]]
>>> 

පයිතන් 3


3
හොඳයි, නමුත් ප්‍රමාණය මුළු කැබලි ගණනට නොගැලපේ නම් අවසානයේ මූලද්‍රව්‍ය පහත වැටේ, උදා: zip(*[iter(range(7))]*3)ආපසු පැමිණ ආදානයෙන් [(0, 1, 2), (3, 4, 5)]අමතක 6වේ.
ඇල්ෆ්

6

මෙහි සිටින සෑම කෙනෙක්ම අනුකාරක ගැන කතා කරන නිසා. boltonsඒ සඳහා පරිපූර්ණ ක්‍රමයක් ඇත iterutils.chunked_iter.

from boltons import iterutils

list(iterutils.chunked_iter(list(range(50)), 11))

ප්‍රතිදානය:

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
 [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
 [22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32],
 [33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43],
 [44, 45, 46, 47, 48, 49]]

නමුත් ඔබට මතකය කෙරෙහි දයාව දැක්වීමට අවශ්‍ය නැතිනම්, ඔබට පරණ ක්‍රම භාවිතා කර සම්පූර්ණ දේම listමුලින් ගබඩා කළ හැකිය iterutils.chunked.


අනුකාරකයන් දෙස බලන අනුපිළිවෙල නොසලකා මෙය සැබවින්ම ක්‍රියාත්මක වේ !!
පීටර් ගර්ඩ්ස්

6

තවත් එක් විසඳුමක්

def make_chunks(data, chunk_size): 
    while data:
        chunk, data = data[:chunk_size], data[chunk_size:]
        yield chunk

>>> for chunk in make_chunks([1, 2, 3, 4, 5, 6, 7], 2):
...     print chunk
... 
[1, 2]
[3, 4]
[5, 6]
[7]
>>> 

5
def chunks(iterable,n):
    """assumes n is an integer>0
    """
    iterable=iter(iterable)
    while True:
        result=[]
        for i in range(n):
            try:
                a=next(iterable)
            except StopIteration:
                break
            else:
                result.append(a)
        if result:
            yield result
        else:
            break

g1=(i*i for i in range(10))
g2=chunks(g1,3)
print g2
'<generator object chunks at 0x0337B9B8>'
print list(g2)
'[[0, 1, 4], [9, 16, 25], [36, 49, 64], [81]]'

1
පළමු වරට ප්‍රවේශ වීමට පෙර දෙවන උප ලැයිස්තුව මුද්‍රණය කිරීමට ඔබට අවශ්‍ය නම් මෙය ඇත්ත වශයෙන්ම ක්‍රියාත්මක වන අතර, එය iT = ඊළඟ (g2) සැකසිය හැකිය; i1 = ඊළඟ (g2); i0 භාවිතා කිරීමට පෙර i1 භාවිතා කරන්න, එය කැඩී යන්නේ නැත !!
පීටර් ගර්ඩ්ස්

5

Matplotlib.cbook කෑලි භාවිතා කිරීම සලකා බලන්න

උදාහරණයක් වශයෙන්:

import matplotlib.cbook as cbook
segments = cbook.pieces(np.arange(20), 3)
for s in segments:
     print s

ඔබ අහම්බෙන් ගිණුම් දෙකක් නිර්මාණය කළ බව පෙනේ. ඔබ හැකි කණ්ඩායම හා සම්බන්ධ ඔබ ඔබේ දායකත්වයන් මත ඍජු සංස්කරණය කිරීම සඳහා වරප්රසාද නැවත කිරීමට ඉඩ ඇත ඔවුන් ඒකාබද්ධ කිරීමට.
ජෝර්ජි
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.