Skip to content

Translate/itertools #1139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: 3.13
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
301 changes: 300 additions & 1 deletion library/itertools.po
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,8 @@ msgid ""
"If the input is an iterator, then fully consuming the *islice* advances the "
"input iterator by ``max(start, stop)`` steps regardless of the *step* value."
msgstr ""
"若輸入為疊代器,則完整耗盡 *islice* 會使輸入的疊代器向前移動 ``max(start, "
"stop)`` 步,與 *step* 的值無關。"

#: ../../library/itertools.rst:513
msgid "Return successive overlapping pairs taken from the input *iterable*."
Expand Down Expand Up @@ -1332,6 +1334,8 @@ msgid ""
"`Cartesian product <https://en.wikipedia.org/wiki/Cartesian_product>`_ of "
"the input iterables."
msgstr ""
"輸入可疊代物的 `笛卡爾乘積 <https://en.wikipedia.org/wiki/"
"Cartesian_product>`_"

#: ../../library/itertools.rst:592
msgid ""
Expand Down Expand Up @@ -1601,10 +1605,14 @@ msgid ""
"`tee` calls to share the same underlying data chain and to have a single "
"update step rather than a chain of calls."
msgstr ""
"當輸入的 *iterable* 已經是一個 tee 疊代物件時,回傳的 tuple(元組)中所有成員"
"都會被建立,就如同它們是由上游的 :func:`tee` 呼叫所產生的一樣。這個「展平步"
"驟 (flattening step)」讓巢狀的 :func:`tee` 呼叫能共享相同的底層資料鏈,並以單"
"一的更新步驟取代一連串的呼叫。"

#: ../../library/itertools.rst:734
msgid "The flattening property makes tee iterators efficiently peekable:"
msgstr ""
msgstr "展平特性讓 tee 疊代器具備高效的預覽能力:"

#: ../../library/itertools.rst:736
msgid ""
Expand All @@ -1613,6 +1621,10 @@ msgid ""
" [forked_iterator] = tee(tee_iterator, 1)\n"
" return next(forked_iterator)"
msgstr ""
"def lookahead(tee_iterator):\n"
" \"回傳下一個值,但不推進輸入\"\n"
" [forked_iterator] = tee(tee_iterator, 1)\n"
" return next(forked_iterator)"

#: ../../library/itertools.rst:743
msgid ""
Expand Down Expand Up @@ -1969,6 +1981,171 @@ msgid ""
" while True:\n"
" yield function()"
msgstr ""
"from collections import Counter, deque\n"
"from contextlib import suppress\n"
"from functools import reduce\n"
"from math import comb, prod, sumprod, isqrt\n"
"from operator import itemgetter, getitem, mul, neg\n"
"\n"
"def take(n, iterable):\n"
" \"回傳可疊代物件的前 n 個元素為串列。\"\n"
" return list(islice(iterable, n))\n"
"\n"
"def prepend(value, iterable):\n"
" \"在可疊代物件前插入單一值。\"\n"
" # prepend(1, [2, 3, 4]) → 1 2 3 4\n"
" return chain([value], iterable)\n"
"\n"
"def tabulate(function, start=0):\n"
" \"回傳 function(0), function(1), ...\"\n"
" return map(function, count(start))\n"
"\n"
"def repeatfunc(function, times=None, *args):\n"
" \"重複呼叫一個帶指定引數的函式。\"\n"
" if times is None:\n"
" return starmap(function, repeat(args))\n"
" return starmap(function, repeat(args, times))\n"
"\n"
"def flatten(list_of_lists):\n"
" \"將巢狀結構攤平一層。\"\n"
" return chain.from_iterable(list_of_lists)\n"
"\n"
"def ncycles(iterable, n):\n"
" \"回傳序列的元素重複 n 次。\"\n"
" return chain.from_iterable(repeat(tuple(iterable), n))\n"
"\n"
"def loops(n):\n"
" \"執行 n 次的迴圈。類似 range(n) 但不建立整數序列。\"\n"
" # for _ in loops(100): ...\n"
" return repeat(None, n)\n"
"\n"
"def tail(n, iterable):\n"
" \"回傳一個疊代器,疊代最後 n 個元素。\"\n"
" # tail(3, 'ABCDEFG') → E F G\n"
" return iter(deque(iterable, maxlen=n))\n"
"\n"
"def consume(iterator, n=None):\n"
" \"將疊代器往前推進 n 步。如果 n 為 None,則完全消耗。\"\n"
" # 使用以 C 語言的速度消耗疊代器的函式。\n"
" if n is None:\n"
" deque(iterator, maxlen=0)\n"
" else:\n"
" next(islice(iterator, n, n), None)\n"
"\n"
"def nth(iterable, n, default=None):\n"
" \"回傳第 n 個元素或預設值。\"\n"
" return next(islice(iterable, n, None), default)\n"
"\n"
"def quantify(iterable, predicate=bool):\n"
" \"給定一個回傳 True 或 False 的判斷函式,計算為 True 的結果。\"\n"
" return sum(map(predicate, iterable))\n"
"\n"
"def first_true(iterable, default=False, predicate=None):\n"
" \"回傳第一個為 true 的值,若無則回傳*預設值*。\"\n"
" # first_true([a,b,c], x) → a or b or c or x\n"
" # first_true([a,b], x, f) → a if f(a) else b if f(b) else x\n"
" return next(filter(predicate, iterable), default)\n"
"\n"
"def all_equal(iterable, key=None):\n"
" \"回傳 True,如果所有元素兩兩相等。\"\n"
" # all_equal('4٤௪౪໔', key=int) → True\n"
" return len(take(2, groupby(iterable, key))) <= 1\n"
"\n"
"def unique_justseen(iterable, key=None):\n"
" \"產生唯一的元素,並保留原始順序。只記住剛看見的元素。\"\n"
" # unique_justseen('AAAABBBCCDAABBB') → A B C D A B\n"
" # unique_justseen('ABBcCAD', str.casefold) → A B c A D\n"
" if key is None:\n"
" return map(itemgetter(0), groupby(iterable))\n"
" return map(next, map(itemgetter(1), groupby(iterable, key)))\n"
"\n"
"def unique_everseen(iterable, key=None):\n"
" \"產生唯一的元素,並保留原始順序。記住所有曾見過的元素。\"\n"
" # unique_everseen('AAAABBBCCDAABBB') → A B C D\n"
" # unique_everseen('ABBcCAD', str.casefold) → A B c D\n"
" seen = set()\n"
" if key is None:\n"
" for element in filterfalse(seen.__contains__, iterable):\n"
" seen.add(element)\n"
" yield element\n"
" else:\n"
" for element in iterable:\n"
" k = key(element)\n"
" if k not in seen:\n"
" seen.add(k)\n"
" yield element\n"
"\n"
"def unique(iterable, key=None, reverse=False):\n"
" \"產生排序後的不重複元素。支援不可雜湊的輸入。\"\n"
" # unique([[1, 2], [3, 4], [1, 2]]) → [1, 2] [3, 4]\n"
" sequenced = sorted(iterable, key=key, reverse=reverse)\n"
" return unique_justseen(sequenced, key=key)\n"
"\n"
"def sliding_window(iterable, n):\n"
" \"將資料收集成重疊的固定長度區段或區塊。\"\n"
" # sliding_window('ABCDEFG', 4) → ABCD BCDE CDEF DEFG\n"
" iterator = iter(iterable)\n"
" window = deque(islice(iterator, n - 1), maxlen=n)\n"
" for x in iterator:\n"
" window.append(x)\n"
" yield tuple(window)\n"
"\n"
"def grouper(iterable, n, *, incomplete='fill', fillvalue=None):\n"
" \"將資料收集成不重疊的固定長度區段或區塊。\"\n"
" # grouper('ABCDEFG', 3, fillvalue='x') → ABC DEF Gxx\n"
" # grouper('ABCDEFG', 3, incomplete='strict') → ABC DEF ValueError\n"
" # grouper('ABCDEFG', 3, incomplete='ignore') → ABC DEF\n"
" iterators = [iter(iterable)] * n\n"
" match incomplete:\n"
" case 'fill':\n"
" return zip_longest(*iterators, fillvalue=fillvalue)\n"
" case 'strict':\n"
" return zip(*iterators, strict=True)\n"
" case 'ignore':\n"
" return zip(*iterators)\n"
" case _:\n"
" raise ValueError('Expected fill, strict, or ignore')\n"
"\n"
"def roundrobin(*iterables):\n"
" \"以循環方式依序輸入可疊代物件,直到全部耗盡。\"\n"
" # roundrobin('ABC', 'D', 'EF') → A D E B F C\n"
" # 演算法出自 George Sakkis\n"
" iterators = map(iter, iterables)\n"
" for num_active in range(len(iterables), 0, -1):\n"
" iterators = cycle(islice(iterators, num_active))\n"
" yield from map(next, iterators)\n"
"\n"
"def subslices(seq):\n"
" \"回傳序列的所有連續非空子切片。\"\n"
" # subslices('ABCD') → A AB ABC ABCD B BC BCD C CD D\n"
" slices = starmap(slice, combinations(range(len(seq) + 1), 2))\n"
" return map(getitem, repeat(seq), slices)\n"
"\n"
"def iter_index(iterable, value, start=0, stop=None):\n"
" \"回傳在序列或可疊代物件中某值出現的索引位置。\"\n"
" # iter_index('AABCADEAF', 'A') → 0 1 4 7\n"
" seq_index = getattr(iterable, 'index', None)\n"
" if seq_index is None:\n"
" iterator = islice(iterable, start, stop)\n"
" for i, element in enumerate(iterator, start):\n"
" if element is value or element == value:\n"
" yield i\n"
" else:\n"
" stop = len(iterable) if stop is None else stop\n"
" i = start\n"
" with suppress(ValueError):\n"
" while True:\n"
" yield (i := seq_index(value, i, stop))\n"
" i += 1\n"
"\n"
"def iter_except(function, exception, first=None):\n"
" \"將一個 call-until-exception 轉換為疊代器介面。\"\n"
" # iter_except(d.popitem, KeyError) → 非阻塞的字典疊代器\n"
" with suppress(exception):\n"
" if first is not None:\n"
" yield first()\n"
" while True:\n"
" yield function()"

#: ../../library/itertools.rst:1008
msgid "The following recipes have a more mathematical flavor:"
Expand Down Expand Up @@ -2100,3 +2277,125 @@ msgid ""
" n -= n // prime\n"
" return n"
msgstr ""
"def multinomial(*counts):\n"
" \"多重集合的不同排列數。\"\n"
" # Counter('abracadabra').values() → 5 2 2 1 1\n"
" # multinomial(5, 2, 2, 1, 1) → 83160\n"
" return prod(map(comb, accumulate(counts), counts))\n"
"\n"
"def powerset(iterable):\n"
" \"來自可疊代物件的子序列,從最短到最長。\"\n"
" # powerset([1,2,3]) → () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)\n"
" s = list(iterable)\n"
" return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))\n"
"\n"
"def sum_of_squares(iterable):\n"
" \"將輸入值的平方加總。\"\n"
" # sum_of_squares([10, 20, 30]) → 1400\n"
" return sumprod(*tee(iterable))\n"
"\n"
"def reshape(matrix, columns):\n"
" \"將 2 維矩陣重新塑形為指定的行數。\"\n"
" # reshape([(0, 1), (2, 3), (4, 5)], 3) → (0, 1, 2), (3, 4, 5)\n"
" return batched(chain.from_iterable(matrix), columns, strict=True)\n"
"\n"
"def transpose(matrix):\n"
" \"交換 2 維矩陣的列和行。\"\n"
" # transpose([(1, 2, 3), (11, 22, 33)]) → (1, 11) (2, 22) (3, 33)\n"
" return zip(*matrix, strict=True)\n"
"\n"
"def matmul(m1, m2):\n"
" \"矩陣相乘。\"\n"
" # matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)]) → (49, 80), (41, 60)\n"
" n = len(m2[0])\n"
" return batched(starmap(sumprod, product(m1, transpose(m2))), n)\n"
"\n"
"def convolve(signal, kernel):\n"
" \"\"\"兩個可疊代物件的離散線性捲積。\n"
" 等同於多項式相乘。\n"
"\n"
" 在數學上捲積是可交換的;但輸入的處理方式不同。\n"
" 訊號以惰性方式被讀取,且可以是無限;核心會在計算開始前被全部讀取。\n"
"\n"
" 文章:https://betterexplained.com/articles/intuitive-convolution/\n"
" 影片:https://www.youtube.com/watch?v=KuXjwB4LzSA\n"
" \"\"\"\n"
" # convolve([1, -1, -20], [1, -3]) → 1 -4 -17 60\n"
" # convolve(data, [0.25, 0.25, 0.25, 0.25]) → 移動平均(模糊)\n"
" # convolve(data, [1/2, 0, -1/2]) → 一階導數估計\n"
" # convolve(data, [1, -2, 1]) → 二階導數估計\n"
" kernel = tuple(kernel)[::-1]\n"
" n = len(kernel)\n"
" padded_signal = chain(repeat(0, n-1), signal, repeat(0, n-1))\n"
" windowed_signal = sliding_window(padded_signal, n)\n"
" return map(sumprod, repeat(kernel), windowed_signal)\n"
"\n"
"def polynomial_from_roots(roots):\n"
" \"\"\"由多項式的根計算其係數。\n"
"\n"
" (x - 5) (x + 4) (x - 3) 展開為: x³ -4x² -17x + 60\n"
" \"\"\"\n"
" # polynomial_from_roots([5, -4, 3]) → [1, -4, -17, 60]\n"
" factors = zip(repeat(1), map(neg, roots))\n"
" return list(reduce(convolve, factors, [1]))\n"
"\n"
"def polynomial_eval(coefficients, x):\n"
" \"\"\"在指定值計算多項式的值。\n"
"\n"
" 此方法在數值穩定性上比 Horner 方法更好。\n"
" \"\"\"\n"
" # 計算 x³ -4x² -17x + 60 在 x = 5\n"
" # polynomial_eval([1, -4, -17, 60], x=5) → 0\n"
" n = len(coefficients)\n"
" if not n:\n"
" return type(x)(0)\n"
" powers = map(pow, repeat(x), reversed(range(n)))\n"
" return sumprod(coefficients, powers)\n"
"\n"
"def polynomial_derivative(coefficients):\n"
" \"\"\"計算多項式的一階導數。\n"
"\n"
" f(x) = x³ -4x² -17x + 60\n"
" f'(x) = 3x² -8x -17\n"
" \"\"\"\n"
" # polynomial_derivative([1, -4, -17, 60]) → [3, -8, -17]\n"
" n = len(coefficients)\n"
" powers = reversed(range(1, n))\n"
" return list(map(mul, coefficients, powers))\n"
"\n"
"def sieve(n):\n"
" \"小於 n 的質數。\"\n"
" # sieve(30) → 2 3 5 7 11 13 17 19 23 29\n"
" if n > 2:\n"
" yield 2\n"
" data = bytearray((0, 1)) * (n // 2)\n"
" for p in iter_index(data, 1, start=3, stop=isqrt(n) + 1):\n"
" data[p*p : n : p+p] = bytes(len(range(p*p, n, p+p)))\n"
" yield from iter_index(data, 1, start=3)\n"
"\n"
"def factor(n):\n"
" \"n 的質因數。\"\n"
" # factor(99) → 3 3 11\n"
" # factor(1_000_000_000_000_007) → 47 59 360620266859\n"
" # factor(1_000_000_000_000_403) → 1000000000000403\n"
" for prime in sieve(isqrt(n) + 1):\n"
" while not n % prime:\n"
" yield prime\n"
" n //= prime\n"
" if n == 1:\n"
" return\n"
" if n > 1:\n"
" yield n\n"
"\n"
"def is_prime(n):\n"
" \"回傳 True,若 n 為質數。\"\n"
" # is_prime(1_000_000_000_000_403) → True\n"
" return n > 1 and next(factor(n)) == n\n"
"\n"
"def totient(n):\n"
" \"計算不大於 n 且與 n 互質的自然數個數。\"\n"
" # https://mathworld.wolfram.com/TotientFunction.html\n"
" # totient(12) → 4 因爲 len([1, 5, 7, 11]) == 4\n"
" for prime in set(factor(n)):\n"
" n -= n // prime\n"
" return n"