Diskuze: Úprava obsahu seznamu s funkcí range() Zdroj: https://www.itnetwork.cz/python/zaklady/seznamy-v-pythonu-jejich-zakladni-funkce-a-metody

Člen

Zobrazeno 32 zpráv z 32.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
len(cisla) # délka/length pole, tj. počet prvků v poli
range(len(cisla)) # vytvoří objekt, který obsahuje čísla od 0 do délky (ne včetně) pole cisla tj. <0, 1, 2, 3, 4, 5, 6, 7, 8, 9>
For cyklus potom postupně přes index i přičítá ke každému číslu 1
cisla[i] += 1
# je totéž jako
cisla[i] = cisla[i] + 1
Proměná i obsahuje aktuální index, i = 0, cisla[0] = 1
Na konci děláme print, abychom se podívali na modifikované pole.
A fakt se nauč posílat kód jako kód tlačítkem </>
range(1, 11) // vytvori pole [1, 2, 3 ... 11] // len(pole) je ale 10 prvvku
range(len(cisla) // vytvori pole 0, 1, ... 10
5 in range(1,11)
5 in [1, 2, 3, 4.. 11] // true
for i in range(1,11)
for i in [1, 2, 3, 4.. 11]
for i in pole
for pos=0; pos<len(pole); pos++) i = pole[pos]
cisla[i] += 1
cisla[i] = cisla[i] + 1
cisla[i] ++
cisla[i] += 5
cisla[i] = cisla[i] + 5
cisla = list(range(1, 11))
cisla = new object List (from array [1, 2, 3, ... 11]) # objekt list ma nejake specialni funkce,
# proto to asi z array prevadel
for i in range(len(cisla)):
cisla = [1, 2, ... 11]
len (cisla) = 10 prvku
range(10) = range(0,10,+1) = 0 az 10 s narustem +1
cisla = [1, 2, ... 11]
#for i in range(len(cisla)):
for (i=0; i<=10l i++)
cisla[i] += 1
print(cisla) # [2, 3, 4, 5]
Ale, nevim, zda to pisu uplne dobre, python nedelam. Zkus mrknout do
dokumentace
https://docs.python.org/…nctions.html
https://docs.python.org/…tdtypes.html#…
Pavel, Peter, moc krát vám děkuji!
Mnohomu už rozumím. Ale otázky jsou:
1. Pavel, poraďte prosím zda máte na mysli, že kód měl by vypadat
takto:
cisla= list(range(1, 11))
for i in range(len(cisla)):
cisla[i] += 1
print(cisla)
Je mi líto, ale nemám tlačítka </>. Ukažte prosím, jak by ten kód měl byt.
2. Podívejte se prosím na kód a otázky:
>cisla= list(range(1, 11)) # rozumím, že to bude vytisknuto tak <[1, 2,
3, 4, 5, 6, 7, 8, 9, 10]> Jo?
>for i in range(len(cisla)): #pro rozsah (range) po celé délce (len)
seznamu (cisla). Je toto správné chápání?
# vytisk byl by tak <0 1 2 3 4 5 6 7 8 9> Jo?
cisla[i] += 1 #v seznamu (cisla) nahraďte hodnoty prvků hodnotami ze seznamu (i), tj. ke každému z nich přidejte 1?
>print(cisla) # vytisk je <[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]>
Ale
<[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]>
< 0 1 2 3 4 5 6 7 8 9>
<[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]>
to hefunguje, ne?
Mohli byste napsat, jakym způsobem ... cyklus potom postupně přes index i
přičítá ke každému číslu 1?
Předem děkuji!
Pozn. Tlacitko </>
nebo >_
je formatovaci
tlacitko editoru zpravy v modrem prouzku, 4te od konce
Ty pole, zkusim ti to ukazat na php
$arr = array(1,2,3,4,5)
$len = count($arr);
for ($i=0; $i<$len; $i++) {$value = $arr[$len];} // tady je jasne, jak dostanes value
for ($arr as $key=>$value) {} // tady k dispozici $key i $value i $arr // key bude 0, 1, 2 ... len
for ($arr as $value) {} // tady k dispozici $value i $arr
for ($arr as &$value) {} // tady k dispozici $value i $arr, $value prepisuje primo hodnotu v array
// v pythonu se tohle zapisuje jako
mylist = list(range(1, 11))
for value in mylist
arr = range(1, 11)
len = len(arr)
for i in range(len)
value = arr[i]
for (i=0; i<len; i++) # nebo, nic ti nebrani pouzit klasicky cyklus
value = arr[i]
Reseni s range by melo byt udajne rychlejsi. Ja pythonakum moc neverim U cyklu zalezi na tom, aby
neprepocitaval hodnoty.
len = len(arr)
for (i=0; i<len; i++) # tady je len staticke cislo
for (i=0; i<len(arr); i++) # tady je len(arr) a ta se musi v kazdem cyklu znova overit,
# protoze jsi v cyklu mohl menit delku pole, takze je cyklus pomalejsi
A pak je tu moznost s range. A tady myslim pythom pouziva jednu specialitku,
on si to range dava do pameti jako pole.
Posun ukazatele v poli o +1 je udajne rychlejsi nez provest i=i+1. Coz muze byt
hodne zajimave pro dlouha pole nebo nekolik cyklu v sobe. U pole v pameti je
primo funkce, ktery ti vrati nasledujici polozku pole. A neni treba tedy
pouzivat pricitani, pokud mas v pameti prednastavenou sekvenci cisel
0 1 2 3 4 5 6 7
, next_i=0, next_i=1, next_i=2 ...
Jinak, python nad array dokaze nad hodnotou volat dalsi funkce, coz ti muze zjednodusit dalsi praci. Jinak bys to musel psat az za dvojteckou.
mylist = list(range(1, 11))
for value in mylist:
dalsi funkce
for tady_neco_udelej in mylist:
dalsi funkce
for value in mylist:
neco_udelej dalsi funkce
oprava, tam melo byt value = arr(i)
for ($i=0; $i<$len; $i++) {$value = $arr[$i];} // tady je jasne, jak dostanes value
Tady máš kód, který ti ukáže co se během cyklu děje:
cisla = list(range(1, 11))
print(40*"-")
print(f"Cisla pred cyklem: {cisla}")
print(40*"-")
for i in range(len(cisla)):
print(f"{20*'-'} {i} {20*'-'}")
print(f'''Stav před: {cisla}
- index i: {i}
- cisla[{i}]: {cisla[i]}''')
cisla[i] += 1
print(f'''Stav po: {cisla}
- index i: {i}
- cisla[{i}]: {cisla[i]}''')
print(40*"-")
print(f"Cisla po cyklu: {cisla}")
print(40*"-")
Doporučuju začít si v Pythonu trošku hrát a měnit věci, abys pochopil
jak to funguje.
Tlačítko pro vložení kódu je součástí editoru (viz obr.), případně může
vkládat kód rovnou mezi tag
Tag nejde zobrazit takže třeba takto https://ctrlv.cz/VWLB
Moc krát Vám děkuji!
Teď ohledně případu všechno rozumím.
cisla= list(range(1, 11))
for i in range(len(cisla)):
cisla[i] += 1
print(cisla)
Samozřejmě to trvalo, ale teď už chápu význam této věty na
přednášce:
„Pakliže chceme upravit hodnoty seznamu v cyklu, musíme k nim přistoupit na
základě jejich indexů:“
i vaše frázi:
„Poté pro smyčku postupně přečísluji index a ke každému přidám 1
Proměná i obsahuje aktuální index, i = 0, cisla[0] = 1“
Všechny ostatní příklady jsou pro mě stále těžké, jen jim nerozumím,
teprve se učím.
Ohledně … Doporučuju začít si v Pythonu trošku hrát a měnit věci, abys
pochopil jak to funguje. … - to stále dělám.
Opravdu pomáhá!
No, to, rychlejsi nez for cyklus bych trosku rozporoval U cyklu zalezi prave na tom, zda
tam daval konstantu nebo funkci len(). Ale urcite tam nejaky bonus bude. A nebo
python nezvlada bezne cykly. A nebo ostatni jazyky maji pro nektere druhy cyklu
nejaka urychleni, ktera treba odpovidaji tem zapisum.
Takhle, pokud by to bylo rychlejsi nez for cyklus, proc neprepsat prekladacem
for cyklus na tento kod? A pak by na tom, jak to napises uz nezalezelo
Takze, se domnivam, ze temi tvrzenimi jsou PYthonaci sami proti sobe, pokud
tedy cykly neprepisuji na rychlejsi formu a tvrdi, ze existuje lepsi forma
Neco jineho je, porovnat to s nejakym jinym jazykem.
Jako, netvrdim, ze to mozne neni, ale mam o tom dlouhodobe pochybnosti.
Ja ted zrovna predelavam nejake kody v js na sortovani, Tak zkoumam, ktere
zapisy jsou vyhodnejsi. Muzu ti dat link a muzes to zkusit prepsat do PY a
porovnat s rychlosti nativni sort funkce.
https://mlich.zam.slu.cz/…/sorting.htm (tam mam zatim jen
code, text si nevsimej)
https://mlich.zam.slu.cz/…g4-pokus.htm - tady mam nejaky
tester
Muzes to zkusit zatizit, dat tam 1.000.000 prvku a spocitat, za jak dlouho to seradi javascript a za jak dlouho python nativnim sortem.
Já jsem si to měřil přes timeit a vychází to cca 10x rychlejší.Vstup by stejný range(n), kde n jsem zkoušel 10, 100, 1000, 10000.
Jinak nejsem pythoňák, jenom než něco tvrdím, tak si to vyzkouším.
Spousta pythoňáků jede mantru, že for cyklus je nejrychlejší protože je v
Pythonu implementovaný v C, aniž by si to zkusili. Jinak tyhle mikrobenchmarky
je třeba brát s rezervou, správně by se to mělo testovat v nějakém
širším kontextu, kde by roli hrál i garbage collection.
K js, zrovna nedávno někdo na yt dělal benchmarky vkládání prvků to pole
přes různé typy for cyklů. Dost záleží na runtimu, tj. browser, jaká
verze Node.js, apod.
Jo, to je mi jasne, ruzne podminky, ruzne vysledky. Ok, ale mohl jsi dat kod.
Ale, PY tu stejne nemam. Tak ja ti budu verit, no Jen mne udivuje, ze se uvadi ruzne
zapisy pro stejnou vec a ze si to neoptimalizuje prekladac.
Kód zde:
import timeit
def cycle_range(numbers: list[int]):
for i in range(len(numbers)):
numbers[i] += 1
def cycle_map(numbers: list[int]) -> list[int]:
return map(lambda number: number + 1, numbers)
def cycle_list_comp(numbers:list[int]) -> list[int]:
return [number + 1 for number in numbers]
# Timing functions
def range_time():
SETUP_CODE = "from __main__ import cycle_range"
TEST_CODE = '''numbers = list(range(1000))
cycle_range(numbers)'''
times = timeit.repeat(setup=SETUP_CODE,
stmt=TEST_CODE,
repeat=10,
number=10000)
print(f'Range: {sum(times)/len(times)}')
def map_time():
SETUP_CODE = "from __main__ import cycle_map"
TEST_CODE = '''numbers = list(range(1000))
cycle_map(numbers)'''
times = timeit.repeat(setup=SETUP_CODE,
stmt=TEST_CODE,
repeat=10,
number=10000)
print(f'Map: {sum(times)/len(times)}')
def list_comp_time():
SETUP_CODE = "from __main__ import cycle_list_comp"
TEST_CODE = '''numbers = list(range(1000))
cycle_list_comp(numbers)'''
times = timeit.repeat(setup=SETUP_CODE,
stmt=TEST_CODE,
repeat=10,
number=10000)
print(f'List comprehension: {sum(times)/len(times)}')
if __name__ == "__main__":
range_time()
map_time()
list_comp_time()
Výsledky na mém postarším PC:
Range: 0.7218018600004144
Map: 0.09179048000078183
List comprehension: 0.4654164599989599
K psaní důležitých věcí v js asi jenom toto video https://www.youtube.com/watch?…
Z kódu a výsledků jsou pro mě zajímavé dvě věci - čas a syntax.
To Python nemá jednoduší zápis pro vytvoření funkce, která má za úkol inkrementovat prvky pole o 1?
Čekal jsem, že výsledné časy nebudou nic extra, ale aby inkrementace 10000 prvků o 1 trvala několik stovek milisekund, to mi přijde strašné i na postarší PC.
Z toho co vidím bych Python nemohl použít pro reálné aplikace.
Za poskytnuté výsledky testů děkuji.
Je to 1000 prvku, 10000x je spustena ta funkce, celé se to pak 10x zopakuje a z opakovani beru prumer, tj. ty cisla je treba podelit 10000, aby to bylo na jeden pruchod. Takova katastrofa to neni.
DarkCoder - Py bych uplne nezatracoval
Pavel - Ty casy se mi moc nezdaji. Samozrejme JS a Firefox funguji trochu
jinak ne tve verze a jde o jiny pc a tak...
https://mlich.zam.slu.cz/…cle-test.htm
23-25 for // delka = 32768, opakovani 100x, source-code se mrkni v prohlizeci, cisla jsou ms
19-23 while
87 map
110 forEach
143 for (entry of list)
Tvuj PY kod jsem spustil zde
https://www.programiz.com/…ne-compiler/
Range: 0.6130037971999627
Map: 0.12096551309987262
List comprehension: 0.36401569730023764
Zkousel jsem tam pridelat while, ale asi jsem neco zvrtal cycle_peter not defined Jo, smazal
se pocitani prumeru.
def cycle_peter(numbers:list[int]) -> list[int]:
len = len(numbers)
i = 0
while i < len:
numbers[i] = numbers[i] + 1
i = i + 1
return numbers
def peter_time():
SETUP_CODE = "from __main__ import cycle_range"
TEST_CODE = '''numbers = list(range(1000))
cycle_peter(numbers)'''
times = timeit.repeat(setup=SETUP_CODE,
stmt=TEST_CODE,
repeat=10,
number=10000)
print(f'Range: {sum(times)}')
Již Pavel upřesnil, že výsledky neodpovídají jednomu průchodu. Což už je o poznání lepší a na jednoduché programátorské hrátky to stačí. 🙂 Syntax mě nijak nenadchla. Jak tam nejsou ukazatele tak to nemůže být ono. 🤣
Když vidím vaše výsledky všech tří způsobů, tak to tak nejspíš bude.
Ve tvém kódu se mi nepozdává použití stejného identifikatoru len pro proměnnou i funkci. A pak na řádku SETUP_CODE máš cycle_range místo cycle_peter.
Jeste je treba opravit v kodu len = len(pole) na xlen = len(pole), nazev promene se nesmi kryt s funkci.
Range: 6.675131721945945
Map: 1.0123107681283727
List comprehension: 3.8355452601099387
cycle_peter: 6.818023988860659
Huste, ze cyklus s 1000 cisly opakovany 10x provadi 7s !!! Ten samy, co je v
js za 0.020s
ten muj js spusteny a upraveny na programiz webu, zalozka JS, dava tyto
vysledky (asi 2.8 rychlejsi nez muj pocitac)
https://www.programiz.com/…ne-compiler/
performance = {};
performance.now = { return new Date().getTime(); }
8
8
66
107
64
Však jsem psal:
Ve tvém kódu se mi nepozdává použití stejného identifikatoru len pro proměnnou i funkci. 😆 Inkrementace 1000 prvku za 20ms mi teda rychlé také nepřijde. 🙂
Ty časy máš nějaké divné, s nadsázkou v duchu inkrementuji prvky pole v hlavě rychleji. 😆
Ted sis to neprecetl ty. Opakuji to 100x pro delku 32768, v tom js, kde to dava 20 ms. Ale, je spis divne, ze v PY je to 6800 ms. Ale, chapu, ze treba po prelozeni do exe to bude lepsi.
Huste, ze cyklus s 1000 cisly opakovany 10x provadi 7s !!! Ten samy, co je v js za 0.020s
Ať je to 1000 nebo 32768 prvků při 100 opakovanich, hodnoty 20ms jsou pro mě vysoké. Ale zřejmě je to pro js v pořádku.
Huste, ze cyklus s 1000 cisly opakovany 10x provadi 7s !!! Ten samy, co je v js za 0.020s
Jestli chapu, tak jde o python kod s timeit.repeat, takze jeste jednou pro pomalejsi. Repeat opakuje benchmark 10x, tj,.vystupem je deset casu, muze nas zajimat minimum, maximum, prumer, median to je celkem fuk. Number udava pocet exekuci kodu v jednom opakovani, tj. kazdy cas v times odpovida 10000 exekucim daneho kodu, pokud chci cas za jednu exekuci musim podelit 10000.
Zobrazeno 32 zpráv z 32.