Development

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • add elements to indexed list locations

    7 answers - 826 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    Hi,
    I have a very simple problem, but do not know an elegant way to
    accomplish this.
    # I have a list of names:
    names = ['clark', 'super', 'peter', 'spider', 'bruce', 'bat']
    # and another set of names that I want to insert into
    # the names list at some indexed locations:
    surnames = { 1: 'kent', 3:'parker', 5:'wayne' }
    # The thing I couldn't figure out is, after I insert a
    # surname the rest of the indices are not valid.
    # That is, the following won't work:
    for i, x in surnames.iteritems():
    names.insert(i,surnames[i])
    I am searching a nice way to do this. For instance, is there a more
    robust way to store indices (as some sort of pointers maybe?)
    - Levent
  • No.1 | | 971 bytes | |

    En/na leventyilmaz (AT) gmail (DOT) com ha escrit:
    Hi,

    I have a very simple problem, but do not know an elegant way to
    accomplish this.

    # I have a list of names:
    names = ['clark', 'super', 'peter', 'spider', 'bruce', 'bat']

    # and another set of names that I want to insert into
    # the names list at some indexed locations:
    surnames = { 1: 'kent', 3:'parker', 5:'wayne' }

    # The thing I couldn't figure out is, after I insert a
    # surname the rest of the indices are not valid.
    # That is, the following won't work:
    for i, x in surnames.iteritems():
    names.insert(i,surnames[i])

    In my previous post I've misunderstood the problem. Here is a valid
    solution:

    keys = surnames.keys()
    keys.sort()
    count = 0
    for i in keys :
    names.insert(i + count, surnames[i])
    count = count + 1

    HTH
  • No.2 | | 2012 bytes | |

    leventyilmaz (AT) gmail (DOT) com wrote:
    # I have a list of names:
    names = ['clark', 'super', 'peter', 'spider', 'bruce', 'bat']

    # and another set of names that I want to insert into
    # the names list at some indexed locations:
    surnames = { 1: 'kent', 3:'parker', 5:'wayne' }

    # The thing I couldn't figure out is, after I insert a
    # surname the rest of the indices are not valid.
    # That is, the following won't work:
    for i, x in surnames.iteritems():
    names.insert(i,surnames[i])

    This seems to work (tested only with what you see below)::

    names = ['clark', 'super', 'peter', 'spider', 'bruce', 'bat']
    surnames = {1:'kent', 3:'parker', 5:'wayne'}
    for index in sorted(surnames, reverse=True):
    names.insert(index, surnames[index])

    names
    ['clark', 'kent', 'super', 'peter', 'parker', 'spider', 'bruce',
    'wayne', 'bat']

    I just did the inserts from right to left, that is, starting at the end.
    That way, after an insert, I don't have to adjust any indices.

    You may also find that if you do a lot of inserts into the list, it may
    be more efficient to create a new list, e.g.::

    names = ['clark', 'super', 'peter', 'spider', 'bruce', 'bat']
    surnames = {1:'kent', 3:'parker', 5:'wayne'}
    new_names = []
    for i, name in enumerate(names):
    if i in surnames:
    new_names.append(surnames[i])
    new_names.append(name)

    new_names
    ['clark', 'kent', 'super', 'peter', 'parker', 'spider', 'bruce',
    'wayne', 'bat']

    STeVe
  • No.3 | | 1173 bytes | |

    leventyilmaz (AT) gmail (DOT) com schrieb:
    Hi,

    I have a very simple problem, but do not know an elegant way to
    accomplish this.

    # I have a list of names:
    names = ['clark', 'super', 'peter', 'spider', 'bruce', 'bat']

    # and another set of names that I want to insert into
    # the names list at some indexed locations:
    surnames = { 1: 'kent', 3:'parker', 5:'wayne' }

    # The thing I couldn't figure out is, after I insert a
    # surname the rest of the indices are not valid.
    # That is, the following won't work:
    for i, x in surnames.iteritems():
    names.insert(i,surnames[i])

    I am searching a nice way to do this. For instance, is there a more
    robust way to store indices (as some sort of pointers maybe?)

    Use a dictionary for both of them?

    The concept of indices is that they IMPLY a position. So either you work
    in a way that you e.g. add the surnames in a defined order and adjust
    the subsequent indices, or you discard the approach entirely and e.g use
    a map of first to surnames.

    Diez
  • No.4 | | 2762 bytes | |

    Thanks for the answers. Enumerating in reverse is indeed quite a smart
    idea.

    The fact is though, I overly simplified the task in the super-hero
    example. In the real case, the dictionary keys are not necessarily the
    indices for inserts; that is to say, the inserts do not necessarily
    take place in some sorted order.

    I think I was thinking more of a linked-list idea, where you do not
    store the indices as integers to some random access array but rather as
    pointers into list's nodes. Then the subsequent inserts would not hurt
    previously stored pointers. For those who know a bit C++/STL here is a
    sketch of the idea:

    name_list heros;
    heros.push_back("clark");
    // add the rest
    indexed_name_list surnames;
    surnames.push_back(
    make_pair( find( heros.begin(), heros.end(), "clark"), "kent") )
    ); // the find function returns an iterator to appropriate location
    // add the rest

    for_each(surnames.begin(), surnames.end(), insert_surnames)
    // insert_surnames is a callback that receives a single indexed surname
    // at a time and does the job, without affecting outer iterators.

    I was wondering how to make indices as *robust* in Python Any ideas?

    PS: following is the compilable code-let of the task in C++

    //
    #include <iostream>
    #include <list>
    #include <vector>
    #include <map>
    #include <string>
    #include <algorithm>

    using namespace std;
    typedef string name;
    typedef pair<list<name>::iterator, stringindexed_name;

    void insert_name( list<name>* into, indexed_name in ) {
    into->insert(in.first, in.second);
    }

    int main() {
    using namespace std;
    // Define super-heros (fathers ignored)
    list<nameheros;
    heros.push_back("super");
    heros.push_back("clark");
    heros.push_back("spider");
    heros.push_back("peter");
    heros.push_back("bat");
    heros.push_back("bruce");

    // Assign father names to proper son
    list<indexed_namesurnames;
    surnames.push_back( // ++ is to have surname inserted _after_ the
    name
    make_pair(++find(heros.begin(),heros.end(),"clark"),
    string("kent"))
    );
    surnames.push_back(
    make_pair(++find(heros.begin(),heros.end(),"peter"),
    string("parker"))
    );
    surnames.push_back(
    make_pair(++find(heros.begin(),heros.end(),"bruce"),
    string("wayne"))
    );

    // Insert surnames succeeding appropriate heros
    for_each(surnames.begin(), surnames.end(),
    bind1st(ptr_fun(insert_name), &heros) );

    // Salute the heros
    copy(heros.begin(),heros.end(),ostream_iterator<string>(cout," "));
    cout << endl;
    return 0;
    }

    //
  • No.5 | | 1957 bytes | |

    In <1150528979.036821.246410 (AT) g10g2000cwb (DOT) googlegroups.com>, levent wrote:

    I think I was thinking more of a linked-list idea, where you do not
    store the indices as integers to some random access array but rather as
    pointers into list's nodes. Then the subsequent inserts would not hurt
    previously stored pointers. For those who know a bit C++/STL here is a
    sketch of the idea:

    name_list heros;
    heros.push_back("clark");
    // add the rest
    indexed_name_list surnames;
    surnames.push_back(
    make_pair( find( heros.begin(), heros.end(), "clark"), "kent") )
    ); // the find function returns an iterator to appropriate location
    // add the rest

    for_each(surnames.begin(), surnames.end(), insert_surnames)
    // insert_surnames is a callback that receives a single indexed surname
    // at a time and does the job, without affecting outer iterators.

    I was wondering how to make indices as *robust* in Python Any ideas?

    What about putting all information for each super hero into an object or
    at least a list? And those objects/lists can then be stored into a
    dictionary with the first name of the heroes as key. Something like this:

    heroes = [['super', 'clark'], ['spider', 'peter'], ['bat', 'bruce']]

    name2hero = dict((hero[1], hero) for hero in heroes)

    fullnames = [['clark', 'kent'], ['peter', 'parker'], ['bruce', 'wayne']]
    for name, surname in fullnames:
    name2hero[name].append(surname)

    for hero in heroes:
    print 'Hello %s a.k.a %s %s' % tuple(hero)

    IMH you shouldn't try to program C++ in Python. Take a step back and
    describe *what* you want to achieve and not *how* you do it in another
    language. And then implement it in Python.

    Ciao,
    Marc 'BlackJack' Rintsch
  • No.6 | | 2908 bytes | |

    levent wrote:

    Thanks for the answers. Enumerating in reverse is indeed quite a smart
    idea.

    The fact is though, I overly simplified the task in the super-hero
    example. In the real case, the dictionary keys are not necessarily the
    indices for inserts; that is to say, the inserts do not necessarily
    take place in some sorted order.

    I think I was thinking more of a linked-list idea, where you do not
    store the indices as integers to some random access array but rather as
    pointers into list's nodes. Then the subsequent inserts would not hurt
    previously stored pointers. For those who know a bit C++/STL here is a
    sketch of the idea:

    name_list heros;
    heros.push_back("clark");
    // add the rest
    indexed_name_list surnames;
    surnames.push_back(
    make_pair( find( heros.begin(), heros.end(), "clark"), "kent") )
    ); // the find function returns an iterator to appropriate location
    // add the rest

    for_each(surnames.begin(), surnames.end(), insert_surnames)
    // insert_surnames is a callback that receives a single indexed surname
    // at a time and does the job, without affecting outer iterators.

    I was wondering how to make indices as *robust* in Python Any ideas?

    Python's list is technically a vector. You can therefore either search for
    the insertion point in a timely fashion:

    heros = ["super", "clark", "spider", "peter", "bat", "bruce"]
    names = [("clark", "kent"), ("peter", "parker"), ("bruce", "wayne")]

    for first, last in names:
    heros.insert(heros.index(first)+1, last)
    print heros

    or you have to snatch a real (linked) list from somewhere. Here's an ad-hoc
    implementation:

    class Node(object):
    def __init__(self, value, next=None):
    self.value = value
    self.right = next
    def __str__(self):
    return "List(%s)" % ", ".join(repr(n.value) for n in self)
    def __iter__(self):
    item = self
    while item:
    yield item
    item = item.right
    def find(self, value):
    for item in self:
    if item.value == value:
    return item
    raise ValueError("%r not found" % (value,))
    def insert_after(self, value):
    self.right = Node(value, self.right)
    @staticmethod
    def from_list(items):
    items = iter(items)
    try:
    first = items.next()
    except StopIteration:
    raise ValueError("empty lists not supported")
    cur = head = Node(first)
    for value in items:
    node = Node(value)
    cur.right = node
    cur = node
    return head

    if __name__ == "__main__":
    heros = ["super", "clark", "spider", "peter", "bat", "bruce"]
    heros = Node.from_list(heros)
    names = [("clark", "kent"), ("peter", "parker"), ("bruce", "wayne")]
    surnames = [(heros.find(f), s) for f, s in names]
    print heros
    for node, value in surnames:
    node.insert_after(value)
    print heros

    Peter
  • No.7 | | 1460 bytes | |

    levent wrote:
    Thanks for the answers. Enumerating in reverse is indeed quite a smart
    idea.

    The fact is though, I overly simplified the task in the super-hero
    example. In the real case, the dictionary keys are not necessarily the
    indices for inserts; that is to say, the inserts do not necessarily
    take place in some sorted order.

    I think I was thinking more of a linked-list idea, where you do not
    store the indices as integers to some random access array but rather as
    pointers into list's nodes. Then the subsequent inserts would not hurt
    previously stored pointers. For those who know a bit C++/STL here is a
    sketch of the idea:

    Sorry, I don't know C++/STL, so I don't understand the example you gave.
    If your dict doesn't already come with the indices, can't you just
    create a dict that does?

    heros = ["super", "clark", "spider", "peter", "bat", "bruce"]
    names = dict(clark="kent", peter="parker", bruce="wayne")
    heros_indices = {}
    for index, hero_word in enumerate(heros):
    if hero_word in names:
    heros_indices[index + 1] = names[hero_word]

    for index in sorted(heros_indices, reverse=True):
    heros.insert(index, heros_indices[index])

    heros
    ['super', 'clark', 'kent', 'spider', 'peter', 'parker', 'bat', 'bruce',
    'wayne']

    STeVe

Re: add elements to indexed list locations


max 4000 letters.
Your nickname that display:
In order to stop the spam: 3 + 2 =
QUESTION ON "Development"

EMSDN.COM