Re: Python sets which support multiple same elements
> Many times when I am writing some program in python, I notice that I > could transform my list into set, then use the set methods like union, > intersection, set equality etc. , and it will solve my problem easily. > But then I realize that if I transform my list into set, it will > remove duplicates of elements in the list and so I will lose > information from my original list. > > For example, I was writing a program to detect whether two strings are > anagrams of each other. I had to write it like this: > > def isAnagram(w1, w2): > w2=list(w2) > for c in w1: > if c not in w2: > return False > else: > w2.remove(c) > return True > > But if there was a data structure in python which supported duplicate > elements(lets call it dset), then I could just write: > > def inAnagram(w1,w2): > return dset(w1)==dset(w2) > > Example of some dset methods: > {1,2,3,3} intersection {4,1,2,3,3,3} == {1,2,3,3} > {1,2,3,3} union {4,1,2,3,3,3} == {1,2,3,3,3,4} > {4,1,2,3,3,3} difference {1,2,3,3} == {4,3} > > Do you think that it would be a good idea to add this kind of data > structure to python? Or did I overlook some other easy way to solve > this kind of problems? I think collections.Counter object may be useful for your purpose. http://docs.python.org/py3k/library/collections.html#collections.Counter -- http://mail.python.org/mailman/listinfo/python-list
Writing multiple files with with-context
To write onto multiple files on the same time (a number of files are variable), I'd like to code as follows, for example, IF I can do, LIST_LEN = 4 with [ open('list_%d.txt' % i, 'w') for i in range(LIST_LEN) ] as fobjlist: for i in range(1000): fobjlist[random.randrange(LIST_LEN)].write(str(i)+"\n") or using a dict object, DICT_KEYS = ('foo', 'bar', 'baz') with { k: open('dict_%s.txt' % k, 'w') for k in DICT_KEYS } as fobjdict: for i in range(1000): fobjdict[random.choice(DICT_KEYS)].write(str(i)+"\n") However, list and dict don't has __exit__ method and so they cannot run. One idea is using contextlib.nested(), from contextlib import nested with nested(*[open('list_%d.txt' % i, 'w') for i in range(LIST_LEN)]) as fobjlist: for i in range(1000): fobjlist[random.randrange(LIST_LEN)].write(str(i)+"\n") with nested(*[open('dict_%s.txt' % k, 'w') for k in DICT_KEYS]) as fobjlist: fobjdict = dict(zip(DICT_KEYS, fobjlist)) #convert list to dict for i in range(1000): fobjdict[random.choice(DICT_KEYS)].write(str(i)+"\n") On Python2.x, this is OK. but 3.x warns that nested() is deprecated. Moreover, on using dict, it is required to convert list to dict. Another idea is to make container classes having __exit__() myself. class MyList(list): def __enter__(self): return [ v.__enter__() for v in self ] def __exit__(self, exc_type, exc_value, traceback): ret = False for v in self: if v.__exit__(exc_type, exc_value, traceback): ret = True exc_type = exc_value = traceback = None return ret class MyDict(dict): def __enter__(self): return { k: v.__enter__() for k, v in self.items() } def __exit__(self, exc_type, exc_value, traceback): ret = False for v in self.values(): if v.__exit__(exc_type, exc_value, traceback): ret = True exc_type = exc_value = traceback = None return ret with MyList( open('list_%d.txt' % i, 'w') for i in range(LIST_LEN) ) as fobjlist: for i in range(1000): fobjlist[random.randrange(LIST_LEN)].write(str(i)+"\n") with MyDict( (k, open('dict_%s.txt' % k, 'w')) for k in DICT_KEYS ) as fobjdict: for i in range(1000): fobjdict[random.choice(DICT_KEYS)].write(str(i)+"\n") I think this is smarter a little than others, but it cannot guaranteed to call __exit__() of members in containers if members are changed during with-context. So, do you have another, more smart and pythonic way? Thanks -- http://mail.python.org/mailman/listinfo/python-list