#python #c# #python-3.x #foreach #generator
Вопрос:
У меня есть этот рабочий код Python, который инвертирует регистр всех символов ввода и возвращает результат:
return ''.join(letter.upper() if letter.islower() else (letter.lower() if letter.isupper() else letter) for letter in input())
В этой строке цикл For находится в конце строки вместо строки вместо того, чтобы быть до или на строке над ней.
Возможно ли это в C #? У меня есть рабочая версия функции ниже, где text1 является вводом, но я могу сжать его только до 3 строк вместо 1:
string result = string.Empty;
foreach(char letter in text1) result = Char.IsLower(letter) ? letter.ToString().ToUpper() : (Char.IsUpper(letter) ? letter.ToString().ToLower() : letter.ToString());
return resu<
Я думал, что этого можно достичь, выполнив это:
return String.Join('', Char.IsLower(letter) ? letter.ToString().ToUpper() : (Char.IsUpper(letter) ? letter.ToString().ToLower() : letter.ToString()) foreach(char letter in text1));
Но синтаксис не позволяет использовать генератор foreach в конце.
Я довольно новичок в C #, поэтому, возможно, я упускаю что-то очевидное, но я не могу найти в Интернете никаких ссылок на наличие генератора в конце такого оператора.
Ответ №1:
(something for x in iterable)
в Python есть специальный синтаксис понимания, который можно использовать для создания списков или генераторов на основе существующего итерируемого. Это специальный синтаксис, который разделяет ключевые слова с обычным for
циклом, но не имеет прямого отношения к обычным циклам. Синтаксис уникален для Python, и в C # для этого нет прямой замены.
Ближайшей подобной языковой конструкцией в C # были бы выражения LINQ, которые точно соответствуют цели, которая часто стоит за пониманием Python. С выражением LINQ вы можете начать с перечислимого (который является итеративным типом .NET), а затем применить фильтры или сопоставления поверх этого, используя методы Where
и Select
LINQ .
Итак, рассмотрим следующий пример на Python:
example = 'Foo Bar!'
result = ''.join(letter.upper() if letter.islower() else (letter.lower() if letter.isupper() else letter) for letter in example)
print(result) #fOO bAR!
Прямой эквивалент в C # с использованием LINQ будет выглядеть следующим образом:
var example = "Foo Bar!";
var result = string.Join("", example.Select(letter =>
char.IsLower(letter) ? char.ToUpper(letter) :
char.IsUpper(letter) ? char.ToLower(letter) : letter
));
Console.WriteLine(result); // fOO bAR!
Это работает, потому что строка является перечислимым числом символов ( IEnumerable<char>
), и поэтому вы можете использовать Select
метод для сопоставления каждой буквы из источника с новым значением.
Комментарии:
1. Почему
string.Join
, когда разделитель является пустой строкой? Можетstring.Concat
ли это сработать здесь? Отличное объяснение и ответ.2. Или
new string(query.ToArray())
3. @OlivierJacot-Descombes да, много вкусов 🙂
4. @zaggler О да,
string.Concat
должно работать так же хорошо. Я обычно используюstring.Join
по привычке, не задумываясь об этом слишком много. Но да, здесь это сработало бы нормально.5. @poke спасибо за отзыв.