Perché Python riduce () salta sull'elemento nessuno?
Domanda
Ho cercato di ottenere il sito di casa di un URL. In primo luogo ho usato un ciclo per loop e ho raggiunto l'obiettivo.
home = ''
my_url = 'http://www.mysite.com/subdir/subdir2/index.html'
for item in my_url.split('/')[:3]:
home += item + '/'
print home
E posso ottenere
'http://www.mysite.com/'
Poi mi imbatto in riduzione () che non avevo mai usato prima. Quindi ho uno scatto, ecco il codice:
my_url = 'http://www.mysite.com/subdir/subdir2/index.html'
home = ''
home = reduce(lambda x,y : x + y + '/',my_url.split('/')[:3])
print home
Questa volta ho ottenuto
'http:/www.mysite.com/'
Riduce solo il momento in cui non ci è la spiegazione del risultato?
Sì, lo so da questo argomento Che potrei semplicemente usare la funzione parser di Urllib per farlo, quindi spero che la discussione sia focalizzata sulla riduzione ()
Soluzione
my_url = 'http://www.mysite.com/subdir/subdir2/index.html'
home = ''
home = reduce(lambda x,y : x + y + '/',my_url.split('/')[:3])
my_url.split('/')[:3] #=> ['http:', '', 'www.mysite.com']
'http:' + '' + '/' #=> 'http:/'
'http:/' + 'www.mysite.com' + '/' #=> 'http:/www.mysite.com/'
Questo non è misterioso. Tutto funziona come previsto - Il problema è che gli URL non sono uniformi, in quanto il protocollo è separato con una doppia barra.
Uno strumento utile per capire come funziona la riduzione scanl
da functional
( http://pypi.python.org/pypi/functional ):
In [11]: home = scanl(lambda x,y : '%s%s/'%(x,y),my_url.split('/')[0],my_url.split('/')[1:3])
In [12]: home
Out[12]: <generator object _scanl at 0x0000000003DEC828>
In [13]: list(home)
Out[13]: ['http:', 'http:/', 'http:/www.mysite.com/']
Notare che str.join
implementa un algoritmo leggermente diverso:
In [16]: '/'.join(my_url.split('/'))
Out[16]: 'http://www.mysite.com/subdir/subdir2/index.html'
Questo è ciò che le persone di solito vogliono - è equivalente a:
In [22]: reduce(lambda x,y : '%s/%s'%(x,y),my_url.split('/'))
Out[22]: 'http://www.mysite.com/subdir/subdir2/index.html'
Altri suggerimenti
Sì, so da questo argomento che potrei semplicemente usare la funzione parser di Urllib per farlo, quindi spero che la discussione si concentri sulla riduzione ()
Non capisco perché vuoi reinventare la ruota se c'è una funzione nella libreria standard per farlo. Ti suggerisco davvero di non perdere tempo e di avere familiarità con la biblioteca standard Pythons e Usa la funzionalità fornita.
Comunque, torna alla tua domanda: quando digio: my_url.split('/')[:3]
Capisco questo:
['http:', '', 'www.mysite.com']
Quindi non c'è no None
In esso, solo una stringa vuota, che può essere usata come qualsiasi altra stringa. E a quanto pare questo è ciò che la tua Lambda funziona per il reduce
L'algoritmo lo fa, concatena solo le corde insieme. Ti suggerisco di usare il strings
join
Metodo, poiché è più leggibile e facile comprensibile:
>>> parts = my_url.split('/')[:3]
>>> print "/".join(parts)
'http://www.mysite.com'
Devi aggiungere l'ultimo /
te stesso, però.