Domanda

In the following code, I am trying to create a new word by iterating over all words fed as arguments of varying length, string type. I read here * operator makes it non keyword optional arguments.

def gen_new_word(word1,*nwords):
new_word=''
t0=[i for i in nwords]
t=max(word1,max(t0))
print (t),str(len(t)) #check largest string
for i in xrange(len(t)):
    try:
        print 'doing iter i# %s and try' %(i)
        new_word=new_word+(word1[i]+nwords[i])
        print new_word
    except IndexError,e:
        print 'entered except'
        c=i
        for x in xrange(c,len(t)):
            print 'doing iter x# %s in except' %(x)
            new_word=new_word+t[x]
        break
return new_word

OUtput:

gen_new_word('janice','tanice','practice')
tanice 6
doing iter i# 0 and try
jtanice
doing iter i# 1 and try
jtaniceapractice
doing iter i# 2 and try
entered except
doing iter x# 2 in except
doing iter x# 3 in except
doing iter x# 4 in except
doing iter x# 5 in except
Out[84]: 'jtaniceapracticenice'

Q1: Instead of giving 'practice'as max string why is max(word1,max(t0)) giving tanice?

Q2: t=max(word1,max(t0)) works but max(word1,nwords) doesn't. Why & Is there a workaround to this?

Q3: In new_word=new_word+(word1[i]+nwords[i]) I want individual letters in strings to show up. Desired result should be 'jtpaarnnaiicccteeice' but is 'jtaniceapracticenice'. due to * nwords gives the first element stored in tuple. I want *nwords to expand it to individual strings. How can I do that? My point being, I don't know in a generic sense how many arguments it may take in.

È stato utile?

Soluzione

Q1: Instead of giving 'practice' as max string why is max(word1,max(t0)) giving tanice

Strings are ordered lexicographically. t > p so tanice is greater than practice

Q2: t=max(word1,max(t0)) works but max(word1,nwords) doesn't. Why & Is there a workaround to this?

This is because max expects either an iterable, or a variable number of arguments. In the latter case, max is trying to compare a string to a list rather than a string to each element in the list. You could use itertools.chain:

max(chain([word1],nwords),key=len)  #assuming you're comparing based on length.

Q3: ...

I'm not really sure what you're going for here. Based on the description, it looks like you want to chain the strings after zipping them together:

from itertools import chain,izip_longest
''.join(chain.from_iterable(izip_longest(word1,*nwords,fillvalue='')))

Here's an example without the function:

>>> from itertools import chain,izip_longest
>>> words = ('janice','tanice','practice')
>>> ''.join(chain.from_iterable(izip_longest(*words,fillvalue='')))
'jtpaarnnaiicccteeice'

The unpacking operator goes both ways. You can use it to say "I want this function to have a variable number of positional arguments":

def foo(*args): ...

Or, "I want to pass this function a variable number of positional arguments":

foo(*iterable)

Here I've used the second form to pass a variable number of strings to izip_longest1 which takes an arbitrary number of positional arguments.

The above code is equivalent to:

''.join(chain.from_iterable(izip_longest('janice','tanice','practice',fillvalue='')))

1zip_longest on python3.x

Altri suggerimenti

>>> max("tanice", "practice")
'tanice'
>>>

You should compare on len(word) not the word itself!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top