Moving list entries from one list to another

Bengt Richter bokr at oz.net
Sun Jul 14 17:43:57 EDT 2002


On Sun, 14 Jul 2002 13:17:09 +0200, JB <jblazi at hotmail.com> wrote:

>Bengt Richter wrote:
>
[...]
>> (Is this like your data? Or how does it differ?)
>
>This is ok. The real data are much longer strings, but it is 
>ok.
A further question: What generates the "id" number, and what do
you need it for besides verifying order? Do you need it as a key
to other data locally or remotely? Or is your concern just guaranteeing
unchanged order as the selection  narrows?

If it's just order, we can probably eliminate them, and gain speed.
If you need the id's, and the rest of the tuple is just a single string item,
then we will gain speed by combining the id into the string, perhaps as a
suffix. The gain will come from having a list of string-only elements so
that we can search for substrings without a subscript operation on a tuple
for every element, and being able to use map or filter using builtin functions.
This may allow simpler approaches with adequate speed.
[...]
>
>> 
>> Here we initialize a search object with a master starting
>> list and nothing selected
>>  >>> is1 = IncSrch(master1)
>>  >>> is1
>> 
>>  >>> `is1`
>>  ''
>> I.e., there is nothing selected to the curr list yet.
>> 
>> Here we do a first search based on containing substring
>> 'D':
>>  >>> is1.new_search('D')
>> Just typing the name calls repr to print the current state
>> of the search object:
>>  >>> is1
>>  (7, 'item_DY')
>> 
>> That wasn't much to do a secondary search on, so we do a
>> new search on the master list for 'B':
>>  >>> is1.new_search('B')
>>  >>> is1
>>  (1, 'item_BX')
>>  (2, 'item_BY')
>>  (3, 'item_BZ')
>>  (5, 'item_BW')
>>  (6, 'item_BW')
>>  (8, 'item_BY')
>> 
>> That got a few, so we incrementally search for 'Y':
>>  >>> is1.inc_search('Y')
>>  >>> is1
>>  (2, 'item_BY')
>>  (8, 'item_BY')
>> 
>> And so forth. Is that the kind of thing you want to do?
>
>Yes.
Well, maybe the question was a little too broad ;-)
My example searched first for 'B' then for 'Y' within the results
of the first search, but it did not search for 'BY'.

This is an important distinction, since you will presumably want
to refine a search for, e.g., Bach by incrementally refining based
on 'B', 'Ba', 'Bac' and 'Bach', but if you want to find his Italian
Concerto, you don't want to continue refining results by searching
them for 'BachI', 'BachIt', 'Bachita', etc. I.e., you are finished
with Bach and should presumably refine further based on 'I', 'It',
'Ita', etc. found anywhere in the entries you have so far.

>
>> I presume you have to pass a list of items in some form to
>> the display widget, and that you will not want to pass
>> more than say MAX_FOR_WIDGET items for a reasonable
>> scrolling display, and you may(??) need the items as a
>> list of strings, not tuples, so you might want to add a
>> first_for_widget() and next_for_widget() method to the
>> class as part of the definition (but I'll do it separately
>> here since I have some state above to use):
>
>Of course, only 40 or so lines can be displayed at the same 
>time. It plays no rôle if I pass list or tuples of strings.
>
You mean no difference if you pass ('x','y','z') or ['x','y','z']?
But I was referring to tuples including the integer id number. IOW,
I wouldn't expect to pass [(24,'x'), (25,'y'), (26,'z')] to a low
level single column dropdown list widget that I wanted to show
x, y and z. So the question is in what form your parameters need
to be passed.

>> If you will comment on what this simple class does and
>> doesn't do that you need functionally, that will establish
>> unambiguous requirements. Then we can make it fast one way
>> or another.
>
>That is exactly. what I want. I do not quite understand in 
>your soulution, what you do, when the search string is 
>shortened by the user. Let us assume, he had typed in "Mo" 
>(for Mozart) but then he decides he is looking for "Me" 
>(another composer). So he deletes the "o". What happens 
>then? This is, why I thought, I should need two lists.

There's a number of things you could do. You will note that
the class does have two lists: self.master and self.curr.
Of course, self.master is just a reference to the starting
list passed to the __init__ method, since we haven't re-bound
self.master.

The simple thing would be just to call new_search('M')
when the user deletes 'o' from 'Mo', and then inc_search('Me')
when s/he types the 'e', and so forth.

But if we want to do multiple words, we probably want to
re-search on the results from the previous complete word,
not the original master list. We could keep track of
previous complete-word results in a separate list and copy
self.curr to it when we start a new word, and start all over
with new searches on the master list when the user wants
to abandon a previous word.

We could modify the interface so that the search object
handles multiple words internally if we pass them as
blank-separated words plus the trailing word fragment that
the user is currently typing or backspacing over. This
way we only need a single search method, though it will be
more complicated.

Once this really nails your functional requirements, we can
see about performance. If you anticipate a really large database,
you might want to consider a relational database to do primary
selections. And/or you might want to get the first 40 results
quickly for user feedback and let a separate thread work on a
full search while the user ponders.

As you notice, we are now a long way from discussing just
"Moving list entries from one list to another" ;-)

You may yet want to do something like that, but let's get
the role of the id cleared up, and the functionality settled first.

Regards,
Bengt Richter



More information about the Python-list mailing list