1

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.

user2290820
  • 2,709
  • 5
  • 34
  • 62
  • Are you trying to find words that A) can be built using some/all the letters from words passed into the function i.e passing in `he` and `root`, one value returned would be `hero`. AND/OR B) literally trying to combined the words to form a larger word: passing in `sled` and `dog` would give `sleddog`. – HennyH May 01 '13 at 12:26
  • With `max` you are not comparing the _length_, but the lexical position (t is after p in the alphabet). Thus `tanice > practice`. Example: `print max('hello', 'goodbye')` gives `hello`. – Floris May 01 '13 at 12:27
  • I'm having a hard time seeing what it is that you actually want to have returned here. Could you elaborate on that? Maybe we can come up with a more elegant way to do it. – mgilson May 01 '13 at 12:28

2 Answers2

1

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

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • In Q3, I was trying to achieve exactly that and in a better way! Yes, that answers all of my questions and gives me more functions to look at in the documentation. Thanks. – user2290820 May 01 '13 at 16:52
0
>>> max("tanice", "practice")
'tanice'
>>>

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

mgilson
  • 300,191
  • 65
  • 633
  • 696
Bhavish Agarwal
  • 663
  • 7
  • 13