Пользовательский ввод и отсортированные списки в Python 3 - PullRequest
0 голосов
/ 12 мая 2018

Мне нужна помощь в создании вывода, подобного этому:

1. Enter a member: samantha 
Names: ['Samantha']
2. Enter a member: susan 
Names: ['Samantha', 'Susan']
3. Enter a member: billy 
Names: ['Billy', 'Samantha', 'Susan']
4. Enter a member: billy
4. Enter a member: samantha
4. Enter a member: Jason 
Names: ['Billy', 'Jason', 'Samantha', 'Susan']
5. Enter a member: 

Members:
1. Billy
2. Jason
3. Samantha
4. Susan

Я попытался создать программу, которая делает это, но безрезультатно. Я буду комментировать мои вопросы в самом коде. Заранее спасибо за помощь.

def function():

    x = []
    #a = "1." # I tried to number the questions by adding these but it doesnt work
    while True:
        #a += 1
        name = input("Enter name: ").title()
        x.append(name)

        print("Names:", x)
        #if name == name: # this condition is made so that an input that is typed in again doesn't get included in the list
            #name = input("Enter name: ").title()

            # where should I add an insert() here to have the list alphabetically ordered?

        if not name: # pressing enter prints out the second half of the output, listing the members
            #print("\nMembers:", x).sort()
            break

function()

Ответы [ 7 ]

0 голосов
/ 12 мая 2018

Я сохранил большую часть вашей структуры, но исправил довольно много вещей. Чтобы получить нумерацию, я использовал оператор форматирования строки%. Вы также можете использовать str.format, , который многие предпочитают .

Вы можете отсортировать список на месте (список заменяется отсортированным списком) с помощью x.sort(). Чтобы проверить, находится ли что-либо в списке, используйте thing is in mylist или thing is not in mylist

def function():

    x = []
    a = 1
    while True:
        prompt = '%d. Enter a member: ' % a
        name = input(prompt)
        name = name.title() # convert first letter to uppercase

        if name.strip() == '':  # enter or empty string entered
            print()
            print('Members:')
            for idx, item in enumerate(x):
                print('%d. %s' % (idx+1, item))
            break
        elif name not in x:
            x.append(name)
            x.sort()  # sort x in place
            print("Names: ", x)
            a += 1


function()

и мой вывод:

1. Enter a member: samantha
Names:  ['Samantha']
2. Enter a member: susan
Names:  ['Samantha', 'Susan']
3. Enter a member: billy
Names:  ['Billy', 'Samantha', 'Susan']
4. Enter a member: Jason
Names:  ['Billy', 'Jason', 'Samantha', 'Susan']
5. Enter a member:

Members:
1. Billy
2. Jason
3. Samantha
4. Susan


------------------
(program exited with code: 0)

Press any key to continue . . .
0 голосов
/ 22 мая 2019
def fun1():
    l = []
    while True:
        s = input("Enter a name or '-1' to quit: ")
        if s=='-1':
            break
        l.append(s)
    l.sort()
    print("The sorted names or numbers(whatever) are:")
    print(l)
fun1()
0 голосов
/ 12 мая 2018

Лично я бы предпочел использовать set, чтобы избежать дублирования более чистым способом, и я бы также объединил две секции печати в отдельную функцию. Поэтому я предлагаю следующее, которое немного отличается от вашего, но (на мой взгляд) проще:

def print_members(members):
    numbered_members = enumerate(sorted(members), 1)
    print("Members:", ", ".join(
        "{}. {}".format(*tup) for tup in numbered_members))


def collect_members():
    members = set()
    while True:
        next_member_num = len(members) + 1
        name = input("{}. Enter a member: ".format(next_member_num)).title()
        if name:
            members.add(name)
            print_members(members)
        else:
            print_members(members)
            return

Обратите внимание, что сортировка (необходимая здесь только для функции print_members) станет очень дорогой, если число членов возрастет слишком сильно, и в этом случае я бы предложил использовать двоичное дерево поиска вместо набора.

0 голосов
/ 12 мая 2018

Вам не нужно много изменений в вашем коде.Основная реструктуризация включает перемещение всех исключений, таких как повторение имен и отсутствие ввода в начало цикла.Дополнительные пояснения включены в комментарии.

def function():
    x = []
    #no need to keep track of the number of members, the list length will give us this information
    #infinite loop that will be interrupted, when no input is given 
    while True:
        #determine length of list, +1 because Python index starts with 0
        n = len(x) + 1
        #ask for input, format prints the number into the bracket position
        name = input("{}. Enter a member: ".format(n))
        #check if name already in list
        if name in x:
            #if name in list, ignore the input and start while loop again
            continue
        #no input - print out members and stop
        if not name: 
            print("Members:")
            #get for each member the index number i
            for i, member in enumerate(x):
                #print index in position {0} and member name in position {1}
                print("{0}. {1}".format(i + 1, member))
            #leave function()
            return
        #append name and sort list
        x.append(name)
        x.sort()        
        #print list
        print("Names:", x)


function()
0 голосов
/ 12 мая 2018

Вы сделали почти все правильно, но проблема в том, что вы выходите из цикла. Сначала вы добавляете имя, а затем проверяете, был ли ввод просто вводом. Итак, сначала проверьте вход, а затем добавьте его в список. Вот мой код:

def fun1():
    l = []
    while True:
        s = input("Enter a member: ")
        if not s:
            break
        l.append(s.title())
        print("Names:", l)
    l.sort()
    print("Members:")
    for i in range(0, len(l)):
        print(i+1,end = '')
        print(".", l[i])
fun1()

Надеюсь, это поможет.

0 голосов
/ 12 мая 2018

getPositionByBinarySearch не реализован, поэтому вы можете реализовать его самостоятельно.

def getPositionByBinarySearch(arr, name):
    """
    implement binary search to find the index at which insertion should happen)
    return -1 if insertion is not needed (exact match is found)
    """

def func():
    arr = []
    while True:
        name = input(str(len(x)+1) + '. Enter a number: ')
        if not name:
            print "Members:"
            for i, member in enumerate(members):
                print(str(i+1) + '. ' + member)
            break;
        pos = getPositionByBinarySearch(arr, name)
        if (pos != -1):
            arr = arr[:i] + [name] + arr[i:]
0 голосов
/ 12 мая 2018

Это один из способов реализации вашей логики.

def function():

    x = []

    while True:

        name = input('{0}. Enter a member: '.format(len(x)+1)).title()

        if not name in x:
            x.append(name)
            x.sort()
            print('Names:', x)

        if len(x) == 4:
            break

    print('Members:')
    print('\n'.join(['{0}. {1}'.format(i, j) for i, j in enumerate(x)]))

Объяснение

  • Используйте list.append, list.sort и печатайте имена, только когда name не в x.
  • Похоже, вы хотите максимум 4 имени. В этом случае break, когда len(x) достигает 4.
  • Вы можете использовать понимание списка с str.format для окончательного вывода.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...